-- AceConfig, AceGUI = LibStub("AceConfig-3.0"), LibStub("AceGUI-3.0")
local AC, ACD = LibStub("AceConfig-3.0"), LibStub("AceConfigDialog-3.0")

-- Main Stuff
	--[[local]] GStar, GS = ... -- todo: once initial development is done change this to a local @framework
	GS.DefaultSettings = {
		Shout = 6673
	}

	function GS.Initialize()
		if not GS.InitFrame then
			GS.InitFrame = CreateFrame("Frame")
			GS.InitFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
			GS.InitFrame:RegisterEvent("ADDON_LOADED")
			GS.InitFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
			GS.InitFrame:RegisterEvent("PARTY_LEADER_CHANGED")
			GS.InitFrame:SetScript("OnEvent", GS.OnEvent)
			GS.Frames = {}
			if not GS.Frames.Throttle then GS.FramesSetup() end
		end
	end

	function GS.OnEvent(self, origevent, ...)
		if origevent == "ADDON_LOADED" and ... == "GStar" then
			if not GSR then GSR = {} end
			if not GSR.Settings then GSR.Settings = GS.DefaultSettings end
			GS.InitFrame:UnregisterEvent("ADDON_LOADED")
		end
		if origevent == "PLAYER_ENTERING_WORLD" then
			if not GS.Frames.MonitorParent then GS.MonitorSetup() end
			if not GSR.Class then GSR.Class = select(2, UnitClass("player")) end
			if not GSR.Race then GSR.Race = select(2, UnitRace("player")) end
			if not GS.Spec then GS.Spec = GetSpecialization() end
			GS.Start = false
			GS.AnimationMaintenance("off")
			GS.InitFrame:SetScript("OnUpdate", GS.Rotation)
		end
		if origevent == "PLAYER_SPECIALIZATION_CHANGED" then GS.Spec = GetSpecialization() end
		if origevent == "PLAYER_LEAVING_WORLD" then
			-- GS.InitFrame:SetScript("OnUpdate", nil)
			-- GS.Frames.TargetList:SetScript("OnUpdate", nil)
			-- GS.Frames.Throttle:SetScript("OnUpdate", nil)
		end
	end

	function GS.Rotation()
		-- local timedebug = debugprofilestop()
		if not FireHack then return end
		if not GS.RanOnce then
			-- if GSR.TutorialRun == nil then GSR.TutorialRun = true end
			-- RequestPage("https://code.google.com/p/gstar/wiki/VersionCheck", GS.Update) -- l0l1dk
			if GSR.TimelessIsle then print("Timeless Isle Buffs script loaded.") end
			if GSR.Slowfall then print("Slowfall script loaded.") end
			GS.RanOnce = true
		end

		if buttonyes and buttonyes:IsShown() then
			GS.AnimationMaintenance("off")
			GS.Start = false
			return
		end

		if GSR.Slowfall then GS.Slowfall() end

		if GS.Start and not UnitIsDeadOrGhost("player") then
			GS.AnimationMaintenance("on")
			if GS[GSR.Class..GS.Spec] then
				GS[GSR.Class..GS.Spec]()
				return
			else
				print("No Rotation for this Specialization and Class combo.")
				GS.Start = false
				GS.AnimationMaintenance("off")
				return
			end
		end
	end

-- Meat
	GS.TargetsPreliminary, GS.Targets, GS.TTDM, GS.TTD, GS.Ignore = {}, {}, {}, {}, {}
	GS.Players, GS.PlayersPreliminary = {}, {}
	GS.Players[1], GS.Players[2], GS.Players[3] = {Player = "Tanks", Players = {}}, {Player = "Healers", Players = {}}, {Player = "DPS", Players = {}}
	GS.CastDebug = {}
	local lowestMob, highestMob, maxHP = nil, nil, math.huge
	local interruptChannel = false
	ThokThrottle = 0
	GS.BossList = {
		-- Headless Horseman
		"Headless Horseman";
		"Head of the Horseman";
		-- Scholomance
		"Instructor Chillwind";
		"Jandice Barov";
		"Rattlegore";
		"Lilian Voss";
		"Darkmaster Gandling";
		-- Scarlet Halls
		"Flameweaver Koegler";
		-- Cataclysm
		"Admiral Ripsnarl";
		"Altairus";
		"Ammunae";
		"Anraphet";
		"Argaloth";
		"Asaad";
		"Ascendant Lord Obsidius";
		"Augh";
		"Beauty";
		"Chimaeron";
		"Commander Ulthok";
		"Corborus";
		"Corla Herald of Twilight";
		"Drahga Shadowburner";
		"Earthrager Ptah";
		"Elementium Monstrosity";
		"Erudax";
		"Erunak Stonespeaker";
		"Foe Reaper 5000";
		"Forgemaster Throngus";
		"General Husam";
		"General Umbriss";
		"Glubtok";
		"Grand Vizier Ertan";
		"Halfus Wyrmbreaker";
		"Helix Gearbreaker";
		"High Priestess Azil";
		"High Prophet Barim";
		"Isiset";
		"Karsh Steelbender";
		"Lady Naz'jar";
		"Lockmaw";
		"Mindbender Ghur'sha";
		"Nefarian";
		"Ozruk";
		"Ozumat";
		"Rajh";
		"Rom'ogg Bonecrusher";
		"Setesh";
		"Siamat";
		"Slabhide";
		"Temple Guardian Anhuur";
		"Valiona";
		"Vanessa VanCleef";
		"Arcanotron";
		"Arion";
		"Atramedes";
		"Cho'gall";
		"Electron";
		"Magmatron";
		"Toxitron";
		"Feludius";
		"Ignacious";
		"Magmaw";
		"Maloriak";
		"Nezir";
		"Rohash";
		"Sinestra";
		"Terrastra";
		"Anshal";
		"Al'Akir";
		"Akil'zon";
		"Nalorakk";
		"Jan'alai";
		"Halazzi";
		"Hex Lord Malacrass";
		"Daakara";
		"High Priest Venoxis";
		"Bloodlord Mandokir";
		"Hazza'rah";
		"Renataki";
		"Wushoolay";
		"Gri'lek";
		"High Priestess Kilnara";
		"Zan'zil";
		"Jin'do the Godbreaker";
		--// Throne of the Four Winds
		"Anshal";
		"Nezir";
		"Rohash";
		"Al'Akir";
		-- // Firelands
		"Beth'tilac";
		"Lord Rhyolith";
		"Alysrazor";
		"Shannox";
		"Baleroc"; -- , The Gatekeeper
		"Majordomo Staghelm";
		"Ragnaros";
		-- // Dragon Soul
		"Morchok";
		"Warlord Zon'ozz";
		"Yor'sahj the Unsleeping";
		"Hagara the Stormbinder";
		"Ultraxion";
		"Warmaster Blackhorn";
		"Burning Tendons";
		-- The Burning Crusade
		--// Hellfire Ramparts
		"Watchkeeper Gargolmar";
		"Omor the Unscarred";
		"Vazruden the Herald";
		--// The Blood Furnice
		"The Maker";
		"Broggok";
		"Keli'dan the Breaker";
		--// The Shattered Halls
		"Grand Warlock Nethekurse";
		"Warbringer O'mrogg";
		"Blood Guard Porung";
		"Warchief Kargath Bladefist";
		--// The Slave Pens
		"Mennu the Betrayer";
		"Rokmar the Crackler";
		"Quagmirran";
		--// The Steamvault
		"Hydromancer Thespia";
		"Mekgineer Steamrigger";
		"Warlord Kalithresh";
		--// The Underbog
		"Hungarfen";
		"Swamplord Musel'ek";
		"Ghaz'an";
		"The Black Stalker";
		--// The Escape from Durnholde
		"Lieutenant Drake";
		"Captain Skarloc";
		"Epoch Hunter";
		--// Auchenai Crypts
		"Shirrak the Dead Watcher";
		"Exarch Maladaar";
		--// Mana Tombs
		"Pandemonius";
		"Tavarok";
		"Nexus-Prince Shaffar";
		--// Sethekk Halls
		"Darkweaver Syth";
		"Talon King Ikiss";
		"Anzu";
		--// Shadow Labyrinth
		"Ambassador Hellmaw";
		"Blackheart the Inciter";
		"Grandmaster Vorpil";
		"Murmur";
		-- Wrath of the Lich King
		--// Utguarde Keep
		"Prince Keleseth";
		"Skarvald the Constructor";
		"Ingvar the Plunderer";
		--// Utguarde Pinnacle
		"Svala Sorrowgrave";
		"Gortok Palehoof";
		"Skadi the Ruthless";
		"King Ymiron";
		--// Drak'Tharon Keep
		"Trollgore";
		"Novos the Summoner";
		"King Dred";
		"The Prophet Tharon'ja";
		--// Gundrak
		"Slad'ran";
		"Drakkari Colossus";
		"Eck the Ferocious";
		"Moorabi";
		"Gal'darah";
		--// Violet Hold
		"Erekem";
		"Moragg";
		"Ichoron";
		"Xevozz";
		"Lavanthor";
		"Zuramat the Obliterator";
		"Cyanigosa";
		--// Ahnkahet the old kingdom
		"Elder Nadox";
		"Herald Volazj";
		"Prince Taldaram";
		"Jedoga Shadowseeker";
		--// Azjol-Nerub
		"Krik'thir the Gatewatcher";
		"Hadronox";
		"Anub'arak";
		--// The Culling of Stratholme
		"Meathook";
		"Salramm the Fleshcrafter";
		"Chrono-Lord Epoch";
		"Mal'Ganis";
		"Infinite Corruptor";
		--// The Nexus
		"Ormorok the Tree-Shaper";
		"Grand Magus Telestra";
		"Keristrasza";
		"Anomalus";
		--// Halls of Lightning
		"General Bjarngrim";
		"Volkhan";
		"Ionar";
		"Loken";
		--// Halls of Stone
		"Krystallus";
		"Maiden of Grief";
		"Tribunal of Ages";
		"Sjonnir The Ironshaper";
		--// Eye of Eternity
		"Malygos";
		--// Onyxia's Lair
		"Onyxia";
		--// Ulduar
		"Ignis the Furnace Master";
		"Razorscale";
		"XT-002 Deconstructor";
		"Steelbreaker";
		"Runemaster Molgeim";
		"Stormcaller Brundir";
		"Kologarn";
		"Auriaya";
		"Freya";
		"Hodir";
		"Leviathan Mk II";
		"VX-001";
		"Aerial Command Unit";
		"General Vezax";
		"Yogg-Saron";
		"Algalon the Observer";
		--// Icecrown Citadel
		"Lord Marrowgar";
		"Lady Deathwhisper";
		"Deathbringer Saurfang";
		"Festergut";
		"Rotface";
		"Professor Putricide";
		"Prince Valanar";
		"Prince Keleseth";
		"Prince Taldaram";
		"Blood-Queen Lana'thel";
		"Sindragosa";
		"The Lich King";
		--// Pandaria
		-- Pandaria World Bosses
		"Sha of Anger";
		"Salyis's Warband";
		"Nalak";
		"Oondasta";
		"Chi-Ji";
		"Niuzao";
		"Yu'lon";
		"Xuen";
		"Ordos";
		-- Stormstout Brewery
		"Ook-Ook";
		"Hoptallus";
		"Yan-Zhu the Uncasked";
		-- Temple of the Jade Serpent
		"Wise Mari";
		"Lorewalker Stonestep";
		"Liu Flameheart";
		"Sha of Doubt";
		"Zao Sunseeker";
		"Strife";
		"Peril";
		-- Gate of the Setting Sun
		"Saboteur Kip'tilak";
		"Striker Ga'dok";
		"Commander Ri'mok";
		"Raigonn";
		-- Mogu'shan Palace
		"Kuai the Brute";
		"Haiyan the Unstoppable";
		"Ming the Cunning";
		"Gekkan";
		"Xin the Weaponmaster";
		-- Shado-pan Monastery
		"Gu Cloudstrike";
		"Azure Serpent";
		"Sha of Violence";
		"Master Snowdrift";
		"Corrupted Taran Zhu";
		-- Siege of Niuzao Temple
		"Vizier Jin'bak";
		"Commander Vo'jak";
		"General Pa'valak";
		"Wing Leader Ner'onok";
		-- Heart of Fear
		"Imperial Vizier Zor'lok";
		"Wind Lord Mel'jarak";
		"Blade Lord Ta'yak";
		"Amber-Shaper Un'sok";
		"Garalon";
		"Grand Empress Shek'zeer";
		-- Mogu'shan Vaults
		"Amethyst Guardian";
		"Cobalt Guardian";
		"Jade Guardian";
		"Jasper Guardian";
		"Feng the Accursed";
		"Elegon";
		"The Spirit Kings";
		"Gara'jal the Spiritbinder";
		"Will of the Emperor";
		-- Terrace of Endless Spring
		"Protector Kaolan";
		"Elder Regail";
		"Elder Asani";
		"Lei Shi";
		"Tsulong";
		"Sha of Fear";
		-- Vault of Mysteries
		"Zian of the Endless Shadow";
		"Elegon";
		"Qin-xi";
		"Jan-xi";
		-- Throne of Thunder
		"Jin'rokh the Breaker";
		"Horridon";
		"Sul the Sandcrawler";
		"Kazra'jin";
		"High Priestess Mar'li";
		"Frost King Mala";
		-- Forgotten Depths
		"Tortos";
		"Venomous Head";
		"Frozen Head";
		"Flaming Head";
		"Ji-Kun";
		-- Halls of Flesh Shaping
		"Durumu the Forgotten";
		"Primordius";
		"Dark Animus";
		-- Pinnacle of Storms
		"Ro'shak";
		"Quet'zal";
		"Dam'ren";
		"Iron Qon";
		"Suen";
		"Lu'lin";
		"Lei Shen";
		-- Siege of Orgrimmar
		"Immerseus";
		"Rook Stonetoe";
		"He Softfoot";
		"Sun Tenderheart";
		"Norushen";
		"Hexos";
		"Amalgam of Corruption";
		"Sha of Pride";
		"Galakras";
		"Iron Juggernaut";
		"Earthbreaker Haromm";
		"Wavebinder Kardris";
		"General Nazgrim";
		"Malkorok";
		"Thok the Bloodthirsty";
		"Siegecrafter Blackfuse";
		"Skeer the Bloodseeker";
		"Rik'kal the Dissector";
		"Hisek the Swarmkeeper";
		"Ka'roz the Locust";
		"Korven the Prime";
		"Iyyokuk the Lucid";
		"Xaril the Poisoned Mind";
		"Kaz'tik the Manipulator";
		"Kil'ruk the Wind-Reaver";
		"Garrosh Hellscream";
		-- WoD
		-- Dungeons
		-- Auchindoun
		"Vigilant Kaathar",
		"Soulbinder Nyami",
		"Azzakel",
		"Tern'gor",
		-- Bloodmaul Slag Mines
		"Magmolatus",
		"Slave Watcher Crushto",
		"Roltall",
		"Gug'rokk",
		-- Grimrail Depot
		"Railmaster Rocketspark",
		"Borka the Brute",
		"Nitrogg Thundertower",
		"Skylord Tovra",
		-- Iron Docks
		"Fleshrender Nok'gar",
		"Dreadfang",
		"Ahri'ok Dugru",
		"Makogg Emberblade",
		"Neesa Nox",
		"Oshir",
		"Skulloc",
		"Koramar",
		-- Shadowmoon Burial Grounds
		"Sadana Bloodfury",
		"Nhallish",
		"Bonemaw",
		"Ner'zhul",
		-- Skyreach
		"Ranjit",
		"Araknath",
		"Rukhran",
		"High Sage Viryx",
		-- The Everbloom
		"Witherbark",
		"Life Warden Gola",
		"Earthshaper Telu",
		"Dulhu",
		"Archmage Sol",
		"Xeri'tac",
		"Yalnu",
		-- Upper Blackrock Spire
		"Orebender Gor'ashan",
		"Kyrak",
		"Commander Tharbek",
		"Ironbarb Skyreaver",
		"Ragewing the Untamed",
		"Warlord Zaela",
		-- World Bosses
		"Drov the Ruiner",
		"Tarlna the Ageless",
		"Rukhmar",
		-- Raids
		-- Highmaul
		"Kargath Bladefist",
		"The Butcher",
		"Tectus",
		"Shard of Tectus",
		"Mote of Tectus",
		"Brackenspore",
		-- "Twin Ogron",
		"Pol",
		"Phemos",
		"Ko'ragh",
		"Imperator Mar'gok",
		-- Blackrock Foundry
		"Gruul",
		"oregorger",
		"Beastlord Darmac",
		"Cruelfang",
		"Dreadwing",
		"Ironcrusher",
		"Flambender Ka'graz",
		"Aknor Steelbringer",
		"Hans'gar",
		"Franzok",
		"Operator Thogar",
		-- "Blast Furnance"
		"Kromog",
		-- "The Iron Maidens"
		"Blackhand",
		-- Training Dummies (normal dummy = not boss)
		"Training Dummy";
		"Dungeoneer's Training Dummy",
		"Raider's Training Dummy";
		"Highlord's Nemesis Trainer";
	};
	GS.Dummies = {
		"Training Bag",
		"Training Dummy",
		"Dungeoneer's Training Dummy",
		"Raider's Training Dummy",
		"Small Illusionary Amber-Weaver",
		"Large Illusionary Amber-Weaver",
		"Small Illusionary Mystic",
		"Large Illusionary Mystic",
		"Small Illusionary Guardian",
		"Large Illusionary Guardian",
		"Small Illusionary Slayer",
		"Large Illusionary Slayer",
		"Small Illusionary Varmint",
		"Large Illusionary Varmint",
		"Small Illusionary Banana-Tosser",
		"Large Illusionary Banana-Tosser"
	}
	GS.Ignore.Name = {
		"Manifestation",
		"Kor'Kron Cannon",
		"Spike Mine",
		"Prismatic Crystal"
	}
	GS.Ignore.Type = {
		"Critter",
		"Critter nil",
		"Wild Pet",
		"Pet",
		"Totem"
	}
	GS.tblInRange = {
		"Insanity"
	}
	GS.listInRange = {
		40
	}
	GS.InterruptList = {
		"Arbiter's Hammer",
		"Felblast",
		"Drain Life",
		"Chaos Bolt",
		"Firestorm",
		"Ferocious Yell",
		"Molten Blast",
		"Solar Burst",
		"Revitalizing Waters",
		-- "Rapid Tides",
		-- "Briarskin",
		"Bramble Patch",
		-- "Parasitic Growth",
		"Toxic Bolt",
		"Debilitating Fixation",
		"Decay",
		"Corrupted Blood"
	}
	GS.Throttle = {}
	GS.Throttle.tPlayerCount, GS.Throttle.tTargetCount, GS.Throttle.nPlayerCount, GS.Throttle.nTargetCount = nil, 0, nil, nil
	GS.Throttle.LastTargetList, GS.Throttle.LastTargetMaint = 0, 0

	GS.InterruptID = {WARRIOR = 6552, PALADIN = 96231, MONK = 116075, DEATHKNIGHT = 47528, MAGE = 2139, PRIEST = 15487, ROGUE = 1766, SHAMAN = 57994, HUNTER = 147362}
	GS.TauntID = {WARRIOR = 355, PALADIN = 62124, DRUID = 6795, MONK = 115546, DEATHKNIGHT = 56222}

	GS.Trinkets = {}
	GS.Trinkets.Trinket1 = {}
	GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = nil, nil, nil
	GS.Trinkets.Trinket2 = {}
	GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = nil, nil, nil
	-- Tables for Tier Bonus
		GS.Tier = {}
		GS.Tier.WARRIOR = {}
		GS.Tier.WARRIOR.t17 = {115580, 115581, 115582, 115583, 115584}
		GS.Tier.PALADIN = {}
		GS.Tier.PALADIN.t17 = {115565, 115566, 115567, 115568, 115569}
		GS.Tier.HUNTER = {}
		GS.Tier.HUNTER.t17 = {115545, 115546, 115547, 115548, 115549}
		GS.Tier.ROGUE = {}
		GS.Tier.ROGUE.t17 = {115570, 115571, 115572, 115573, 115574}
		GS.Tier.PRIEST = {}
		GS.Tier.PRIEST.t17 = {115560, 115561, 115562, 115563, 115564}
		GS.Tier.PRIEST.PVP = {}
		GS.Tier.DEATHKNIGHT = {}
		GS.Tier.DEATHKNIGHT.t17 = {115535, 115536, 115537, 115538, 115539}
		GS.Tier.SHAMAN = {}
		GS.Tier.SHAMAN.t17 = {115575, 115576, 115577, 115578, 115579}
		GS.Tier.MAGE = {}
		GS.Tier.MAGE.t17 = {115550, 115551, 115552, 115553, 115554}
		GS.Tier.WARLOCK = {}
		GS.Tier.WARLOCK.t17 = {115585, 115586, 115587, 115588, 115589}
		GS.Tier.MONK = {}
		GS.Tier.MONK.t17 = {115555, 115556, 115557, 115558, 115559}
		GS.Tier.DRUID = {}
		GS.Tier.DRUID.t17 = {115540, 115541, 115542, 115543, 115544}
	-- Tables for Tier Bonus
	local revision = tonumber(ReadFile("\\World of Warcraft\\Interface\\AddOns\\GStar\\Revision.txt"))
	-- Class Specific Stuff
		GS.Druid = {}
		GS.Druid.Rip, GS.Druid.Rake = {}, {}
		GS.Druid.StellarFlareThrottle = {}

		GS.DEATHKNIGHT = {}
		GS.DEATHKNIGHT.Runes = {start = {}, dur = {}, up = {}}

		GS.Paladin = {}
		GS.Paladin.DoubleJeopardy = nil
		GS.Paladin.Seals = {}
		GS.Paladin.Seals.uthersRemaining, GS.Paladin.Seals.liadrinsRemaining, GS.Paladin.Seals.maraadsRemaining, GS.Paladin.Seals.uthersExpires, GS.Paladin.Seals.liadrinsExpires, GS.Paladin.Seals.maraadsExpires, GS.Paladin.Seals.curSeal = nil, nil, nil, nil, nil, nil, nil
		GS.Paladin.DivineShield, GS.Paladin.Stun, GS.Paladin.BlindingLight = 0, 0, 0

		GS.Hunter = {}
		GS.Hunter.PreSteadyFocus = nil
		GS.Hunter.FocusingShotThrottle = 0

		GS.Priest = {}
		GS.Priest.MindHarvest = {}
		GS.Priest.VampiricTouchThrottle = {}
		GS.Priest.Apparitions = 0
		GS.Priest.MindFlay = 0
		GS.Priest.MindFlayLine = 0
		GS.Priest.InsanityLine = 0
		GS.Priest.MindSear = 0
		GS.Priest.MindSearLine = 0
		GS.Priest.SearingInsanityLine = 0
		GS.Priest.DevouringPlague = 0

		GS.Rogue = {}
		GS.Rogue.nSinisters, GS.Rogue.trackSinister = 0, false

		GS.Mage = {}
		GS.Mage.tRuneOfPower, GS.Mage.RuneToggle = 0, 0
		GS.Mage.PC = nil

		GS.Warlock = {}
		GS.Warlock.ImmolateThrottle = {}
		GS.Warlock.UnstableAfflictionThrottle = {}
		GS.Warlock.HandOfGuldanThrottle = 0
		GS.Warlock.HauntThrottle = 0

		GS.Shaman = {}

	function GS.Update(text)
		GS.AnimationMaintenance("off")
		GS.Start = false

		if not revision then GS.TextBox("turn", 1, 1) return end

		local wRevisionU = string.gsub(string.match(text, "r%d"), "r", "")

		if tonumber(wRevisionU) > revision then GS.TextBox("turn", 1) end
	end

	function GS.MonitorSetup()
		GS.Frames.MonitorParent = CreateFrame("Frame", "GS.Frames.MonitorParent", UIParent)
		GS.Frames.MonitorParent:SetFrameStrata("MEDIUM")
		GS.Frames.MonitorParent:SetWidth("64")
		GS.Frames.MonitorParent:SetHeight("64")
		if GSR.MonitorX and GSR.MonitorY then
			GS.Frames.MonitorParent:ClearAllPoints()
			GS.Frames.MonitorParent:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", GSR.MonitorX, GSR.MonitorY)
		else
			GS.Frames.MonitorParent:ClearAllPoints()
			GS.Frames.MonitorParent:SetPoint("CENTER")
		end

		Monitor = GS.Frames.MonitorParent:CreateTexture("Monitor")
		Monitor:SetTexture("Interface\\Addons\\GStar\\GStarMonitor.tga")
		Monitor:SetAllPoints(GS.Frames.MonitorParent)

		AoEOn = GS.Frames.MonitorParent:CreateTexture("AoEOn")
		AoEOff = GS.Frames.MonitorParent:CreateTexture("AoEOff")
		AoEOn:SetTexture("Interface\\Addons\\GStar\\eyes.tga")
		AoEOff:SetTexture("Interface\\Addons\\GStar\\no.tga")

		AoEOn:SetPoint("RIGHT", -10, 3)
		AoEOn:SetSize(20, 20)
		AoEOff:SetPoint("RIGHT", -10, 3)
		AoEOff:SetSize(20, 20)

		CDsOn = GS.Frames.MonitorParent:CreateTexture("CDsOn")
		CDsOff = GS.Frames.MonitorParent:CreateTexture("CDsOff")
		CDsOn:SetTexture("Interface\\Addons\\GStar\\eyes.tga")
		CDsOff:SetTexture("Interface\\Addons\\GStar\\no.tga")

		CDsOn:SetPoint("BOTTOMRIGHT", -10, 4)
		CDsOn:SetSize(20, 20)
		CDsOff:SetPoint("BOTTOMRIGHT", -10, 4)
		CDsOff:SetSize(20, 20)

		GS.Frames.MonitorParent:SetMovable(1)
		GS.Frames.MonitorParent:EnableMouse(true)
		GS.Frames.MonitorParent:RegisterForDrag("LeftButton")
		GS.Frames.MonitorParent:SetScript("OnMouseDown", function() if AoEOff:IsMouseOver() then GS.ToggleAoE() elseif CDsOff:IsMouseOver() then GS.ToggleCDs() end end)
		GS.Frames.MonitorParent:SetScript("OnDragStart", GS.Frames.MonitorParent.StartMoving)
		GS.Frames.MonitorParent:SetScript("OnDragStop", function(self) GSR.MonitorX, GSR.MonitorY = self:GetRect(); GS.Frames.MonitorParent:StopMovingOrSizing() end)
		AoEOn:Hide()
		CDsOn:Hide()
	end

	function GS.Animation(self, elapsed)
		if GS.AoE then
			if not AoEOn:IsVisible() or AoEOff:IsVisible() then
				AoEOn:Show()
				AoEOff:Hide()
			end
			AnimateTexCoords(AoEOn, 512, 256, 64, 64, 29, elapsed, 0.029)
		elseif AoEOn:IsVisible() or not AoEOff:IsVisible() then
			AoEOff:Show()
			AoEOn:Hide()
		end
		if GS.CDs then
			if not CDsOn:IsVisible() or CDsOff:IsVisible() then
				CDsOn:Show()
				CDsOff:Hide()
			end
			AnimateTexCoords(CDsOn, 512, 256, 64, 64, 29, elapsed, 0.029)
		elseif CDsOn:IsVisible() or not CDsOff:IsVisible() then
			CDsOn:Hide()
			CDsOff:Show()
		end
	end

	function GS.AnimationMaintenance(argument)
		if argument == "off" then
			GS.Frames.MonitorParent:SetScript("OnUpdate", nil)

			GS.Frames.MonitorParent:Hide()
		end
		if argument == "on" then
			GS.Frames.MonitorParent:SetScript("OnUpdate", GS.Animation)

			GS.Frames.MonitorParent:Show()
		end
	end

	function GS.FramesSetup()
		if not GS.Frames.Throttle then
			GS.Frames.Throttle = CreateFrame("Frame", "GS.Frames.Throttle", UIParent)
			GS.Frames.Throttle:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
			GS.Frames.Throttle:RegisterEvent("PLAYER_DEAD")
			GS.Frames.Throttle:RegisterEvent("PLAYER_REGEN_DISABLED")
			GS.Frames.Throttle:SetScript("OnEvent", GS.ThrottleFrameFunction)
		end

		if not GS.Frames.TargetList then
			GS.Frames.TargetList = CreateFrame("Frame", "GS.Frames.TargetList", UIParent)
			GS.Frames.TargetList:SetScript("OnUpdate", GS.TargetList)
		end

		if not GS.Frames.Spells then
		   GS.Frames.Spells = CreateFrame("GameTooltip", "GSSpells", UIParent, "GameTooltipTemplate")
		   GSSpells:SetOwner(UIParent, "ANCHOR_NONE")
		end
	end

	function GS.ThrottleFrameFunction(self, registeredevent, ...)
		if registeredevent == "PLAYER_REGEN_DISABLED" then
			GS.CombatStart = GetTime()
			return
		end

		if registeredevent == "UNIT_COMBO_POINTS" then
			GS.Cast("player", 5171, false, false, false, "SpellToInterrupt")
			GS.Frames.Throttle:UnregisterEvent("UNIT_COMBO_POINTS") -- remove the watching to reduce usage
			return
		end

		if registeredevent == "PLAYER_DEAD" then
			GS.Hunter.PreSteadyFocus = 0
			table.wipe(GS.Warlock.ImmolateThrottle)
			table.wipe(GS.Warlock.UnstableAfflictionThrottle)
			GS.Warlock.HandOfGuldanThrottle = 0
			GS.Warlock.HauntThrottle = 0
			table.wipe(GS.Druid.StellarFlareThrottle)

			GS.Paladin.BlindingLight = 0
			GS.Paladin.DivineShield = 0
			GS.Paladin.Stun = 0
			_ImpendingVictory = false
			_PiercingHowl = false
			_Shockwave = false
			_StormBolt = false
			_Disarm = false
			_IntimidatingShout = false
			_ShatteringThrow = false
			_VictoryRush = false
			_Mend = false
			GS.DeathStrike = false
			GS.DeathSiphon = false
			return
		end

		if registeredevent == "COMBAT_LOG_EVENT_UNFILTERED" then
			local timeNow = GetTime()
			local timestamp, event, hidecaster, sourceguid, sourcename, sourceflags, sourceraidflags, destguid, destname, destflags, destraidflags, spellid, spellname, spellschool, failedtype = ...

			-- if spellid == 114207 and event == "SPELL_CAST_SUCCESS" then GS.SkullBanner = GetTime()+10 return end

			if event == "UNIT_DIED" then
				-- warlock 
					if GS.Warlock.HauntThrottle == 2 and destguid == GS.Warlock.HauntTarget then GS.Warlock.HauntThrottle = 0 end -- unthrottle haunt when the in flight target dies

				return
			end

			if sourcename ~= UnitName("player") and sourcename ~= "Thok the Bloodthirsty" and sourcename ~= "Pol" then return end -- no need to run

			if event == "SPELL_CAST_START" then
				-- Thok
					if GSR.Thok and sourcename == "Thok the Bloodthirsty" and spellname == "Deafening Screech" then ThokThrottle = select(6, UnitCastingInfo("boss1"))/1000 return end

				-- Pol
					if GSR.Thok and sourcename == "Pol" and spellname == "Interrupting Shout" then
						if UnitCastingInfo("boss1") == "Interrupting Shout" then
							ThokThrottle = select(6, UnitCastingInfo("boss1"))/1000
						elseif UnitCastingInfo("boss2") == "Interrupting Shout" then
							ThokThrottle = select(6, UnitCastingInfo("boss2"))/1000
						end
					end

				-- Franzok
					if GSR.Thok and sourcename == "Franzok" and spellname == "Disrupting Roar" then
						if UnitCastingInfo("boss1") == "Disrupting Roar" then
							ThokThrottle = select(6, UnitCastingInfo("boss1"))/1000
						elseif UnitCastingInfo("boss2") == "Disrupting Roar" then
							ThokThrottle = select(6, UnitCastingInfo("boss2"))/1000
						end
					end

				-- Hunter
					if spellid == 152245 then GS.Hunter.FocusingShotThrottle = 7 return end

				-- warlock
					if spellid == 348 and timeNow - GS.CastDebug.time < .1 then
						GS.Warlock.ImmolateThrottle[UnitGUID(GS.CastDebug.guid)] = 9
						return
					end
					if spellid == 48181 then GS.Warlock.HauntThrottle = 1 return end
					if spellid == 30108 and timeNow - GS.CastDebug.time < .1 then
						GS.Warlock.UnstableAfflictionThrottle[UnitGUID(GS.CastDebug.guid)] = 9
						return
					end

				-- Priest
					if spellid == 34914 and timeNow - GS.CastDebug.time < .1 then
						GS.Priest.VampiricTouchThrottle[UnitGUID(GS.CastDebug.guid)] = 9
						return
					end

				-- druid
					if spellid == 152221 and timeNow - GS.CastDebug.time < .1 then
						GS.Druid.StellarFlareThrottle[UnitGUID(GS.CastDebug.guid)] = 9
						return
					end

				return
			end

			if event == "SPELL_CAST_FAILED" then

				-- warrior
					if spellid == 6673 or spellid == 469 then -- last shout
						GSR.Shout = spellid
						return
					end
					if spellid == 103840 and not _ImpendingVictory then -- impending victory
					_ImpendingVictory = true
					return
					end
					if spellid == 12323 and not _PiercingHowl then -- piercing howl
						_PiercingHowl = true
						return
					end
					if spellid == 46968 and not _Shockwave then -- shockwave
						_Shockwave = true
						return
					end
					if spellid == 107570 and not _StormBolt then -- stormbolt
						_StormBolt = true
						return
					end
					if spellid == 676 and not _Disarm then -- disarm
						_Disarm = true
						return
					end
					if spellid == 5246 and not _IntimidatingShout then -- intimidating shout
						_IntimidatingShout = true
						return
					end
					if spellid == 64382 and not _ShatteringThrow then -- shattering throw
						_ShatteringThrow = true
						return
					end
					if spellid == 34428 and not _VictoryRush then -- victory rush
						_VictoryRush = true
						return
					end

				-- paladin
					if spellid == 115750 and GS.SpellCDDuration(115750) < 5 then -- blinding light
						GS.Paladin.BlindingLight = 1
						return
					end
					if spellid == 642 and GS.SpellCDDuration(642) <= 10 then -- divine shield
						GS.Paladin.DivineShield = 1
						return
					end
					if (spellid == 105593 or spellid == 853) and GS.SpellCDDuration(spellid) < 5 then -- paladin stun
						GS.Paladin.Stun = 1
						return
					end

				-- Hunter
					if spellid == 136 then -- mend pet
						_Mend = true
						return
					end
					if spellid == 152245 then GS.Hunter.FocusingShotThrottle = 0 return end

				-- Death Knight
					if spellid == 49998 then -- Death Strike
						GS.DeathStrike = true
						return
					end
					if spellid == 108196 then -- Death Siphon
						GS.DeathSiphon = true
						return
					end

				-- warlock
					if spellid == 348 then -- warlock un throttle immolate
						for k,v in pairs(GS.Warlock.ImmolateThrottle) do
							if v == 9 then GS.Warlock.ImmolateThrottle[k] = 0 end
						end
						return
					end
					if spellid == 48181 then -- un throttle haunt
						GS.Warlock.HauntThrottle = 0
						return
					end
					if spellid == 30108 then -- warlock un throttle unstable affliction
						for k,v in pairs(GS.Warlock.UnstableAfflictionThrottle) do
							if v == 9 then GS.Warlock.UnstableAfflictionThrottle[k] = 0 end
							return
						end
						return
					end

				-- Priest
					if spellid == 34914 then -- priest un throttle vampiric touch
						for k,v in pairs(GS.Priest.VampiricTouchThrottle) do
							if v == 9 then GS.Priest.VampiricTouchThrottle[k] = 0 end
							return
						end
						return
					end

				-- druid
					if spellid == 152221 then
						for k,v in pairs(GS.Druid.StellarFlareThrottle) do
							if v == 9 then GS.Druid.StellarFlareThrottle[k] = 0 end
							return
						end
						return
					end

				-- general stuff such as debugging
					if failedtype == "Can't do that while moving" then print(GS.CastDebug.name) return end

				return
			end

			if event == "SPELL_CAST_SUCCESS" then

				-- warrior
					if spellid == 6673 or spellid == 469 then -- last shout
						GSR.Shout = spellid
						return
					end
					if spellid == 103840 and _ImpendingVictory then -- impending victory
						_ImpendingVictory = false
						return
					end
					if spellid == 12323 and _PiercingHowl then -- piercing howl
						_PiercingHowl = false
						return
					end
					if spellid == 46968 and _Shockwave then -- shockwave
						_Shockwave = false
						return
					end
					if spellid == 107570 and _StormBolt then -- stormbolt
						_StormBolt = false
						return
					end
					if spellid == 676 and  _Disarm then -- disarm
						_Disarm = false
						return
					end
					if spellid == 5246 and  _IntimidatingShout then -- intimidating shout
						_IntimidatingShout = false
						return
					end
					if spellid == 64382 and  _ShatteringThrow then -- shattering throw
						_ShatteringThrow = false
						return
					end
					if spellid == 34428 and _VictoryRush then -- victory rush
						_VictoryRush = false
						return
					end

				-- paladin
					if spellid == 115750 then -- blinding light
						GS.Paladin.BlindingLight = 0
						return
					end
					if spellid == 642 then -- divine shield
						GS.Paladin.DivineShield = 0
						return
					end
					if spellid == 105593 or spellid == 853 then -- paladin stun
						GS.Paladin.Stun = 0
						return
					end

				-- hunter
					if spellid == 136 then -- mend pet
						_Mend = false
						return
					end
					if spellid == 781 and HDDisengage then -- disengage
						HD2()
						return
					end
					if GS.PlayerHasTalent(4, 1) then -- steady focus
						if spellid == 77767 or spellid == 56641 then
							if GS.Hunter.PreSteadyFocus == nil or GS.Hunter.PreSteadyFocus == 0 then
								GS.Hunter.PreSteadyFocus = 1
								return
							end
						end
					end
					if spellid == 152245 then -- focusing shot
						GS.Hunter.FocusingShotThrottle = 0
						return
					end

				-- Death Knight
					if spellid == 49998 then -- Death Strike
						GS.DeathStrike = false
						return
					end
					if spellid == 108196 then -- Death Siphon
						GS.DeathSiphon = false
						return
					end

				-- mage
					if spellid == 116011 then -- mage rune of power
						GS.Mage.RuneToggle = GetTime()+0.5
						GS.Mage.tRuneOfPower = GetTime()
						return
					end
					if spellid == 84714 then -- frozen orb
						tFrozenOrb = GetTime()
						return
					end

				-- warlock
					if spellid == 348 then -- warlock immolate unthrottle general throttle mob
						GS.Warlock.ImmolateThrottle[destguid] = 8
						return
					end
					if spellid == 48181 then
						GS.Warlock.HauntThrottle = 2
						GS.Warlock.HauntTarget = destguid
						return
					end 
					if spellid == 30108 then -- warlock un throttle unstable affliction
						GS.Warlock.UnstableAfflictionThrottle[destguid] = 8
						return
					end
					if spellid == 105174 then -- warlock hand of guldan in flight
						GS.Warlock.HandOfGuldanThrottle = 1
						return
					end

				-- priest
					if spellid == 34914 then -- priest vampiric touch unthrottle general throttle mob
						GS.Priest.VampiricTouchThrottle[destguid] = 8
						return
					end
					if GS.PlayerHasGlyph(162532) and spellid == 8092 then -- priest mind harvest
						GS.Priest.MindHarvest[destguid] = 1
						return
					end
					if spellid == 147193 and GS.PlayerHasTalent(7, 3) then -- priest add to apparitions in flight
						GS.Priest.Apparitions = GS.Priest.Apparitions + 1
						return
					end
					if spellid == 155521 then -- priest subtract to apparition in flight
						GS.Priest.Apparitions = GS.Priest.Apparitions - 1
						return
					end
					if spellid == 15407 or spellid == 48045 or spellid == 129197 or spellid == 179338 then -- flay sear insanity
						if spellid == 15407 or spellid == 129197 then
							local ticktime = (3/(1+GetHaste()*.01)/4)
							GS.Priest.MindFlay = ticktime
							if spellid == 15407 then
								GS.Priest.MindFlayLine = tonumber(string.match(GS.DebugStack, "%d+"))
							else
								GS.Priest.InsanityLine = tonumber(string.match(GS.DebugStack, "%d+"))
							end
						elseif spellid == 48045 or spellid == 179338 then
							local ticktime = (5/(1+GetHaste()*.01)/5)
							GS.Priest.MindSear = ticktime
							if spellid == 48045 then
								GS.Priest.MindSearLine = tonumber(string.match(GS.DebugStack, "%d+"))
							else
								GS.Priest.SearingInsanityLine = tonumber(string.match(GS.DebugStack, "%d+"))
							end
						end
						return
					end
					if spellid == 2944 then
						local ticktime = (6/(1+GetHaste()*.01)/6)
						GS.Priest.DevouringPlague = ticktime
					end

				-- rogue
					if spellid == 14183 and GS.SnD == true then -- SnD opener macro
						GS.SnD = true
						GS.Cast("player", 5171, false, false, false, "SpellToInterrupt")
						return
					end
					if GS.Rogue.trackSinister and spellid == 1752 then -- track sinister strikes for combat
						GS.Rogue.nSinisters = GS.Rogue.nSinisters + 1
						if GS.Rogue.nSinisters >= 3 then GS.Rogue.trackSinister = false end
						return
					end

				-- druid
					if spellid == 152221 then -- balance throttle stellar flare
						GS.Druid.StellarFlareThrottle[destguid] = 8
						return
					end

				return
			end

			if event == "SPELL_AURA_APPLIED" or event == "SPELL_AURA_REFRESH" then

				-- hunter
					if spellid == 118253 then -- survival hunter serpent sting
						_G[destguid.."_tSerpentSting"] = GetTime()
						return
					end
					if spellid == 177668 then -- steady focus
						GS.Hunter.PreSteadyFocus = 0
						return
					end

				-- rogue
					if spellid == 137573 then -- rogue burst of speed
						GS.RogueBOS = false
						return
					end
					if spellid == 84746 then -- track sinister strikes for combat
						GS.Rogue.trackSinister = true
						GS.Rogue.nSinisters = 0
						return
					end
					if spellid == 84747 then -- turn off tracking for combat
						GS.Rogue.nSinisters = 0
						return
					end

				-- warlock
					if spellid == 157736 then -- warlock unthrottle immolate specific mob
						GS.Warlock.ImmolateThrottle[destguid] = 0
						return
					end
					if spellid == 30108 then -- warlock unthrottle unstable affliction specific mob
						GS.Warlock.UnstableAfflictionThrottle[destguid] = 0
						return
					end
					if spellid == 48181 then -- unthrottle haunt
						GS.Warlock.HauntThrottle = 0
						return
					end
					if spellid == 47960 then -- warlock hand of guldan no longer in flight
						GS.Warlock.HandOfGuldanThrottle = 0
						return
					end

				-- priest
					if spellid == 34914 then -- priest unthrottle vampiric touch specific mob
						GS.Priest.VampiricTouchThrottle[destguid] = 0
						return
					end

				-- druid
					if spellid == 152221 then -- balance throttle stellar flare
						GS.Druid.StellarFlareThrottle[destguid] = 0
						return
					end

				return
			end
			return
		end
	end

	tanksIndex, healersIndex, dpsIndex = nil, nil, nil
	function GS.TargetList()
		if UnitIsDeadOrGhost("player") then return end
		if not FireHack then return end

		if GetTime() - GS.Throttle.LastTargetList > 0.5 then
			for i = #GS.TargetsPreliminary, 1, -1 do table.remove(GS.TargetsPreliminary, i) end -- mobs
			for i = #GS.PlayersPreliminary, 1, -1 do table.remove(GS.PlayersPreliminary, i) end -- players
			local targetsSize = #GS.TargetsPreliminary
			local playersSize = #GS.PlayersPreliminary
			for i = 1, ObjectCount() do
				local object = ObjectWithIndex(i)
				if bit.band(ObjectType(object), 0x8) > 0 and not UnitInParty(object) then -- mobs
					GS.TargetsPreliminary[targetsSize+1] = object
					targetsSize = targetsSize + 1
					-- table.insert(GS.TargetsPreliminary, object)
				end
				if GSR.Healing then
					if bit.band(ObjectType(object), 0x8) > 0 and bit.band(ObjectType(object), 0x10) == 0 and UnitInParty(object) then -- mobs with party
						GS.PlayersPreliminary[playersSize+1] = object
						playersSize = playersSize + 1
						-- table.insert(GS.PlayersPreliminary, object)
					end 
					if bit.band(ObjectType(object), 0x10) > 0 and UnitGUID("player") ~= UnitGUID(object) then -- players
						GS.PlayersPreliminary[playersSize+1] = object
						playersSize = playersSize + 1
						-- table.insert(GS.PlayersPreliminary, object)
					end 
					if bit.band(ObjectType(object), 0x10) > 0 and UnitGUID("player") == UnitGUID(object) then -- player
						GS.PlayersPreliminary[playersSize+1] = UnitGUID(object)
						playersSize = playersSize + 1
						-- table.insert(GS.PlayersPreliminary, UnitGUID(object))
					end
				end
			end
			GS.Throttle.LastTargetList = GetTime()
		elseif GetTime() - GS.Throttle.LastTargetMaint > 0.15 then
			local targetsSize = #GS.Targets
			for i = 1, #GS.TargetsPreliminary do -- add filtered mobs
				local object = GS.TargetsPreliminary[i]
				if UnitExists(object)
				and UnitHealth(object) > 0
				and not tContains(GS.Targets, object)
				and not tContains(GS.Ignore.Name, UnitName(object))
				and not tContains(GS.Ignore.Type, UnitCreatureType(object))
				and UnitCanAttack("player", object)
				then
					GS.Targets[targetsSize+1] = object
					targetsSize = targetsSize + 1
					-- table.insert(GS.Targets, object)
				end
				if UnitName(object) == "Prismatic Crystal" then
					GS.Mage.PC = object
				end
			end

			if GSR.Healing then
				local tanksFound, healersFound, dpsFound = false, false, false
				for i = 1, #GS.Players do
					local object = GS.Players[i].Player
					if object == "Tanks" then
						tanksIndex = i
						tanksFound = true
					elseif object == "Healers" then
						healersIndex = i
						healersFound = true
					elseif object == "DPS" then
						dpsIndex = i
						dpsFound = true
					end
					if tanksFound and healersFound and dpsFound then break end
				end

				local playersSize, tanksSize, healersSize, dpsSize = #GS.Players, #GS.Players[tanksIndex].Players, #GS.Players[healersIndex].Players, #GS.Players[dpsIndex].Players
			   	for i = 1, #GS.PlayersPreliminary do -- filter out players
			   		local object = GS.PlayersPreliminary[i]
			   		if UnitGUID("player") == object then
			   			if UnitExists("player") and GS.PlayersAlready(ObjectPointer("player")) then
			   				if UnitGroupRolesAssigned("player") == "TANK" then
			   					GS.Players[tanksIndex].Players[tanksSize+1] = {Player = UnitGUID("player"), Stats = {Position = {x,y,z}}}
			   					tanksSize = tanksSize + 1
			   				elseif UnitGroupRolesAssigned("player") == "HEALER" then
			   					GS.Players[healersIndex].Players[healersSize+1] = {Player = UnitGUID("player"), Stats = {Position = {x,y,z}}}
			   					healersSize = healersSize + 1
			   				elseif UnitGroupRolesAssigned("player") == "DAMAGER" then
			   					GS.Players[dpsIndex].Players[dpsSize+1] = {Player = UnitGUID("player"), Stats = {Position = {x,y,z}}}
			   					dpsSize = dpsSize + 1
			   				else
			   					GS.Players[playersSize+1] = {Player = UnitGUID("player"), Stats = {Position = {x,y,z}}}
			   					playersSize = playersSize + 1
			   				end
			   			end
			   		else
			   			if UnitExists(object) and UnitInParty(object) and GS.PlayersAlready(object) and UnitName(object) ~=  "Unknown" then
			   				if UnitGroupRolesAssigned(object) == "TANK" or UnitName(object) == "Oto the Protector" then
			   					GS.Players[tanksIndex].Players[tanksSize+1] = {Player = object, Stats = {Position = {x,y,z}}}
			   					tanksSize = tanksSize + 1
			   					-- table.insert(GS.Players[tanksIndex].Players, {Player = object, Stats = {Position = {x,y,z}}})
			   				elseif UnitGroupRolesAssigned(object) == "HEALER" then
			   					GS.Players[healersIndex].Players[healersSize+1] = {Player = object, Stats = {Position = {x,y,z}}}
			   					healersSize = healersSize + 1
			   					-- table.insert(GS.Players[healersIndex].Players, {Player = object, Stats = {Position = {x,y,z}}})
			   				elseif UnitGroupRolesAssigned(object) == "DAMAGER" or UnitName(object) == "Ki the Assassin" or UnitName(object) == "Kavan the Arcanist" or UnitName(object) == "Sooli the Survivalist" then
			   					GS.Players[dpsIndex].Players[dpsSize+1] = {Player = object, Stats = {Position = {x,y,z}}}
			   					dpsSize = dpsSize + 1
			   					-- table.insert(GS.Players[dpsIndex].Players, {Player = object, Stats = {Position = {x,y,z}}})
			   				else
			   					GS.Players[playersSize+1] = {Player = object, Stats = {Position = {x,y,z}}}
			   					playersSize = playersSize + 1
			   					-- table.insert(GS.Players, {Player = object, Stats = {Position = {x,y,z}}})
			   				end
			   			end
			   		end
				end
			end

			-- else
			-- 	for i = 1, #GS.Players[healersIndex].Player do
			-- 		if GS.Players[healersIndex].Players[i].Player == ObjectPointer("player") then break end
			-- 		if i == #GS.Players then table.insert(GS.Players[healersIndex].Players, {Player = ObjectPointer("player"), Stats = {Position = {x,y,z}}}) end
			-- 	end
			-- end

			-- check what needs to be removed
			for i = 1, #GS.Targets do
				local object = GS.Targets[i]
				if not UnitExists(object) or UnitHealth(object) == 0 or not UnitCanAttack("player", object) then _G["remove"..i] = true end
			end

			if GSR.Healing then
				for i = 1, #GS.Players[tanksIndex].Players do
					local object = GS.Players[tanksIndex].Players[i].Player
					if tonumber(object) then
						if not UnitExists(object) or UnitName(object) == "Unknown" or UnitGroupRolesAssigned(object) ~= "TANK" then _G["removePlayersTanks"..i] = true end
					else
						if not UnitExists("player") or UnitName("player") == "Unknown" or UnitGroupRolesAssigned("player") ~= "TANK" then _G["removePlayersTanks"..i] = true end
					end
				end
				for i = 1, #GS.Players[healersIndex].Players do
					local object = GS.Players[healersIndex].Players[i].Player
					if tonumber(object) then
						if not UnitExists(object) or UnitName(object) == "Unknown" or UnitGroupRolesAssigned(object) ~= "HEALER" then _G["removePlayersHealers"..i] = true end
					else
						if not UnitExists("player") or UnitName("player") == "Unknown" or UnitGroupRolesAssigned("player") ~= "HEALER" then _G["removePlayersHealers"..i] = true end
					end
				end
				for i = 1, #GS.Players[dpsIndex].Players do
					local object = GS.Players[dpsIndex].Players[i].Player
					if tonumber(object) then
						if not UnitExists(object) or UnitName(object) == "Unknown" or UnitGroupRolesAssigned(object) ~= "DAMAGER" then _G["removePlayersDPS"..i] = true end
					else
						if not UnitExists("player") or UnitName("player") == "Unknown" or UnitGroupRolesAssigned("player") ~= "DAMAGER" then _G["removePlayersDPS"..i] = true end
					end
				end
				for i = 1, #GS.Players do
					local object = GS.Players[i].Player
					if object ~= "Tanks" and object ~= "Healers" and object ~= "DPS" then
						if tonumber(object) then
							if not UnitExists(object) or UnitName(object) == "Unknown" or UnitGroupRolesAssigned(object) ~= "NONE" then _G["removePlayers"..i] = true end
						else
							if not UnitExists("player") or UnitName("player") == "Unknown" or UnitGroupRolesAssigned("player") ~= "NONE" then _G["removePlayers"..i] = true end
						end
					end
				end
			end

			for i = #GS.Targets, 1, -1 do -- remove what needs to be removed
				if _G["remove"..i] then
					table.remove(GS.Targets, i)
					_G["remove"..i] = false
				end
			end

			if GSR.Healing then
				for i = #GS.Players[tanksIndex].Players, 1, -1 do -- remove players
					if _G["removePlayersTanks"..i] then
						table.remove(GS.Players[tanksIndex].Players, i)
						_G["removePlayersTanks"..i] = false
					end
				end

				for i = #GS.Players[healersIndex].Players, 1, -1 do -- remove players
					if _G["removePlayersHealers"..i] then
						table.remove(GS.Players[healersIndex].Players, i)
						_G["removePlayersHealers"..i] = false
					end
				end

				for i = #GS.Players[dpsIndex].Players, 1, -1 do -- remove players
					if _G["removePlayersDPS"..i] then
						table.remove(GS.Players[dpsIndex].Players, i)
						_G["removePlayersDPS"..i] = false
					end
				end

				for i = #GS.Players, 1, -1 do -- remove players
					if _G["removePlayers"..i] then
						table.remove(GS.Players, i)
						_G["removePlayers"..i] = false
					end
				end

				for k,v in pairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
						if tonumber(v.Player) then
							GS.Players[k].Stats.HealthPercent = GS.Health(GS.Players[k].Player, maxhealth, true)
							GS.Players[k].Stats.Health = GS.Health(GS.Players[k].Player)
							GS.Players[k].Stats.HealthMax = GS.Health(GS.Players[k].Player, true)
							GS.Players[k].Stats.HealthRemaining = GS.Players[k].Stats.HealthMax-GS.Players[k].Stats.Health
						else
							GS.Players[k].Stats.HealthPercent = GS.Health("player", maxhealth, true)
							GS.Players[k].Stats.Health = GS.Health("player")
							GS.Players[k].Stats.HealthMax = GS.Health("player", true)
							GS.Players[k].Stats.HealthRemaining = GS.Players[k].Stats.HealthMax-GS.Players[k].Stats.Health
						end
					else
						for i,b in pairs(GS.Players[k].Players) do
							if tonumber(b.Player) then
								GS.Players[k].Players[i].Stats.HealthPercent = GS.Health(GS.Players[k].Players[i].Player, maxhealth, true)
								GS.Players[k].Players[i].Stats.Health = GS.Health(GS.Players[k].Players[i].Player)
								GS.Players[k].Players[i].Stats.HealthMax = GS.Health(GS.Players[k].Players[i].Player, true)
								GS.Players[k].Players[i].Stats.HealthRemaining = GS.Players[k].Players[i].Stats.HealthMax-GS.Players[k].Players[i].Stats.Health
							else
								GS.Players[k].Players[i].Stats.HealthPercent = GS.Health("player", maxhealth, true)
								GS.Players[k].Players[i].Stats.Health = GS.Health("player")
								GS.Players[k].Players[i].Stats.HealthMax = GS.Health("player", true)
								GS.Players[k].Players[i].Stats.HealthRemaining = GS.Players[k].Players[i].Stats.HealthMax-GS.Players[k].Players[i].Stats.Health
							end
						end
					end
				end

				table.sort(GS.Players[tanksIndex].Players, function(a,b)
					if a.Stats.Health == 0 then return false end
					if b.Stats.Health == 0 then return true end
					return a.Stats.Health < b.Stats.Health
				end)
				table.sort(GS.Players[healersIndex].Players, function(a,b)
					if a.Stats.Health == 0 then return false end
					if b.Stats.Health == 0 then return true end
					return a.Stats.Health < b.Stats.Health
				end)
				table.sort(GS.Players[dpsIndex].Players, function(a,b)
					if a.Stats.Health == 0 then return false end
					if b.Stats.Health == 0 then return true end
					return a.Stats.Health < b.Stats.Health
				end)

				table.sort(GS.Players, function(a,b)
					if a.Players then
						if b.Players then
							if a.Player == "DPS" then return false
							elseif b.Player == "DPS" then return true
							end

							if a.Player == "Healers" and b.Player == "DPS" then return true
							elseif a.Player == "Healers" and b.Player == "Tanks" then return false
							end

							if a.Player == "Tanks" then return true end
						else
				            return false
						end
					elseif b.Players then
						return true
					end
					return a.Stats.Health < b.Stats.Health
				end)

				for k,v in pairs(GS.Players) do
					if v.Player == "Tanks" then tanksIndex = k
					elseif v.Player == "Healers" then healersIndex = k
					elseif v.Player == "DPS" then dpsIndex = k
					end
				end
			end

			GS.Throttle.LastTargetMaint = GetTime()

			-- if ccRS.Auto_Loot
			-- and (GetTime()-ccR_Last_AutoLoot_Scanned) > 1.5
			-- and not ccrPlayerIsCastingOrChanneling()
			-- and GetNumLootItems() == 0
			-- and not GS.Combat()
			-- then
			-- 	for i = 1, #GS.TargetsPreliminary do
			-- 		local obj = GS.TargetsPreliminary[i]
			-- 		if obj
			-- 		and UnitExists(obj)
			-- 		and GS.Distance(obj) <= max(5, (13 / 6) + UnitCombatReach(obj))
			-- 		and not bPauseAutoLoot
			-- 		then
			-- 			if IIsLootable(obj) then
			-- 				IObjectInteract(obj)
			-- 			end
			-- 			if IIsSkinnable(obj) then
			-- 				IObjectInteract(obj)
			-- 			end
			-- 		end
			-- 	end
			-- 	ccR_Last_AutoLoot_Scanned = GetTime()
			-- end
		end

		for i = 1, #GS.Targets do if UnitExists(GS.Targets[i]) and (UnitIsTapped(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) then GS.TTDF(GS.Targets[i]) end end

		for k,v in pairs(GS.TTD) do if not UnitExists(k) then GS.TTD[k] = nil end end
	end

	function GS.ToggleAoE()
		if GS.AoE then
			GS.AoE = false
			print("GStar Rotations: AoE now off.")
		else
			GS.AoE = true
			print("GStar Rotations: AoE now on.")
		end
	end

	function GS.ToggleCDs()
		if GS.CDs then
			GS.CDs = false
			print("GStar Rotations: CDs now off.")
		else
			GS.CDs = true
			print("GStar Rotations: CDs now on.")
		end
	end

	-- ripped from CommanderSirow of the wowace forums
	function GS.TTDF(unit)
		-- Setup trigger (once)
		if not nMaxSamples then
			-- User variables
			nMaxSamples = 15             -- Max number of samples
			nScanThrottle = 0.5             -- Time between samples
		end

		-- Training Dummy alternate between 4 and 200 for cooldowns
		if tContains(GS.Dummies, UnitName(unit)) then if (not GS.TTD[unit] or GS.TTD[unit == 200] == 200) then GS.TTD[unit] = 4 return else GS.TTD[unit] = 200 return end end

		-- if health = 0 then set time to death to negative
		if GS.Health(unit) == 0 then GS.TTD[unit] = -1 return end

		-- Query current time (throttle updating over time)
		local nTime = GetTime()
		if not GS.TTDM[unit] or nTime - GS.TTDM[unit].nLastScan >= nScanThrottle then
			-- Current data
			local data = GS.Health(unit)

			if not GS.TTDM[unit] then GS.TTDM[unit] = {start = nTime, index = 1, maxvalue = GS.Health(unit, max)/2, values = {}, nLastScan = nTime, estimate = nil} end

			-- Remember current time
			GS.TTDM[unit].nLastScan = nTime

			if GS.TTDM[unit].index > nMaxSamples then GS.TTDM[unit].index = 1 end
			-- Save new data (Use relative values to prevent "overflow")
			GS.TTDM[unit].values[GS.TTDM[unit].index] = {dmg = data - GS.TTDM[unit].maxvalue, time = nTime - GS.TTDM[unit].start}

			if #GS.TTDM[unit].values >= 2 then
				-- Estimation variables
				local SS_xy, SS_xx, x_M, y_M = 0, 0, 0, 0

				-- Calc pre-solution values
				for i = 1, #GS.TTDM[unit].values do
					-- Calc mean value
					x_M = x_M + GS.TTDM[unit].values[i].time / #GS.TTDM[unit].values
					y_M = y_M + GS.TTDM[unit].values[i].dmg / #GS.TTDM[unit].values

					-- Calc sum of squares
					SS_xx = SS_xx + GS.TTDM[unit].values[i].time * GS.TTDM[unit].values[i].time
					SS_xy = SS_xy + GS.TTDM[unit].values[i].time * GS.TTDM[unit].values[i].dmg
				end

				-- Few last addition to mean value / sum of squares
				SS_xx = SS_xx - #GS.TTDM[unit].values * x_M * x_M
				SS_xy = SS_xy - #GS.TTDM[unit].values * x_M * y_M

				-- Results
				local a_0, a_1, x = 0, 0, 0

				-- Calc a_0, a_1 of linear interpolation (data_y = a_1 * data_x + a_0)
				a_1 = SS_xy / SS_xx
				a_0 = y_M - a_1 * x_M

				-- Find zero-point (Switch back to absolute values)
				a_0 = a_0 + GS.TTDM[unit].maxvalue
				x = - (a_0 / a_1)

				-- Valid/Usable solution
				if a_1 and a_1 < 1 and a_0 and a_0 > 0 and x and x > 0 then
					GS.TTDM[unit].estimate = x + GS.TTDM[unit].start
				-- Fallback
				else
					GS.TTDM[unit].estimate = nil
				end

			-- Not enough data
			else
				GS.TTDM[unit].estimate = nil
			end
			GS.TTDM[unit].index = GS.TTDM[unit].index + 1 -- enable
		end

		if not GS.TTDM[unit].estimate then
			GS.TTD[unit] = math.huge
		elseif nTime > GS.TTDM[unit].estimate then
			GS.TTD[unit] = -1
		else
			GS.TTD[unit] = GS.TTDM[unit].estimate-nTime
		end
	end
	-- ripped from CommanderSirow of the wowace forums

	function GS.MultiDoT(spell, range)
		-- if _G["_pullMThrottle"..spell] == nil then _G["_pullMThrottle"..spell] = 0 end
		-- if _G["_pullMThrottle"..spell] >= GetTime() then return end
		-- _G["_pullMThrottle"..spell] = GetTime()+.01

		local spelltable = string.gsub(spell, "%s", "")
		spelltable = string.gsub(spelltable, ":", "")

		if not _G["tNoObject"..spelltable] then _G["tNoObject"..spelltable] = {} end
		if not _G["t"..spelltable] then _G["t"..spelltable] = {} end

		if #_G["tNoObject"..spelltable] > 0 then for i = #_G["tNoObject"..spelltable], 1, -1 do table.remove(_G["tNoObject"..spelltable], i) end end
		if #_G["t"..spelltable] > 0 then for i = #_G["t"..spelltable], 1, -1 do table.remove(_G["t"..spelltable], i) end end

		for i = 1, #GS.Targets do
			if ObjectExists(GS.Targets[i]) and UnitExists(GS.Targets[i]) then

				local curobj = GS.Targets[i]

				if (UnitIsTappedByPlayer(curobj) or tContains(GS.Dummies, UnitName(curobj))) and
				not GS.Aura(curobj, "Misery, Sorrow, and Gloom") and not GS.Aura(curobj, "Mark of Anguish") and not GS.Aura(curobj, "Dark Meditation")
				and not GS.Aura(curobj, "Touch of Y'Shaarj") and not GS.Aura(curobj, "Empowered Touch of Y'Shaarj")
				and (not range or range >= GS.Distance(curobj)+GS.CombatReach(curobj)) then
					local name = GS.Aura(curobj, spell, "", "PLAYER") or GS.Aura(curobj, spell, "Feral, Guardian", "PLAYER") or GS.Aura(curobj, spell, "Metamorphosis", "PLAYER") or GS.Aura(curobj, spell, "Lunar", "PLAYER") or GS.Aura(curobj, spell, "Solar", "PLAYER")
					if name then table.insert(_G["t"..spelltable], curobj) end
					if not name and GS.Distance(curobj) <= 50 and UnitCanAttack("player", curobj) --[[and GS.LOS(curobj)]] then table.insert(_G["tNoObject"..spelltable], curobj) end -- fixme: LOS @framework
				end
			end
		end
	end

	function GS.MultiHoT(spell, range)
		if _G["pullPThrottle"..spell] == nil then _G["pullPThrottle"..spell] = 0 end
		if _G["pullPThrottle"..spell] > GetTime() then return end
		_G["pullPThrottle"..spell] = GetTime()+.25

		local spelltable = string.gsub(spell, "%s", "")

		if not _G["tNoObject"..spelltable] then _G["tNoObject"..spelltable] = {} end
		if not _G["t"..spelltable] then _G["t"..spelltable] = {} end

		if #_G["tNoObject"..spelltable] > 0 then for i = #_G["tNoObject"..spelltable], 1, -1 do table.remove(_G["tNoObject"..spelltable], i) end end
		if #_G["t"..spelltable] > 0 then for i = #_G["t"..spelltable], 1, -1 do table.remove(_G["t"..spelltable], i) end end

		for k,v in pairs(GS.Players) do
			if tonumber(v.Player) then
				if UnitExists(v.Player) then
					if not range or range >= GS.Distance(v.Player, nil) then
						local name = GS.Aura(v.Player, spell, "", "PLAYER")
						if name then table.insert(_G["t"..spelltable], v.Player) end
						if not name then table.insert(_G["tNoObject"..spelltable], v.Player) end
					end
				end
			elseif v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
				if UnitExists(ObjectPointer("player")) then
					if not range or range >= GS.Distance(ObjectPointer("player"), nil) then
						local name = GS.Aura(ObjectPointer("player"), spell, "", "PLAYER")
						if name then table.insert(_G["t"..spelltable], ObjectPointer("player")) end
						if not name then table.insert(_G["tNoObject"..spelltable], ObjectPointer("player")) end
					end
				end
			end
		end
	end

	function GS.PMultiplier(spell)
		if spell == "Rake" then
			local multiplier = 1
			if GS.Aura("player", 52610) then multiplier = multiplier * 1.4 end -- need glyph savage roar
			if GS.Aura("player", 5217) then multiplier = multiplier * 1.15 end -- tiger's fury
			if GS.Aura("player", 155672) then multiplier = multiplier * 1.3 end -- blood talons
			return multiplier
		elseif spell == "Rip" then
			local multiplier = 1
			if GS.Aura("player", 52610) then multiplier = multiplier * 1.4 end -- need glyph savage roar
			if GS.Aura("player", 5217) then multiplier = multiplier * 1.15 end -- tiger's fury
			if GS.Aura("player", 155672) then multiplier = multiplier * 1.3 end -- blood talons
			return multiplier
		end
	end

	function GS.Interrupt()
		local spellcasting = UnitCastingInfo("target") or UnitChannelInfo("target")

		if tContains(GS.InterruptList, spellcasting) then
			if GS.InterruptID[GSR.Class] then
				if GS.SIR(GS.InterruptID[GSR.Class]) then
					GS.Cast(nil, GS.InterruptID[GSR.Class])
					return
				end
			else
				if GSR.Class == "DRUID" then -- druid
					if GS.Spec == 1 then
						if GS.SIR(78675) then GS.Cast("target", 78675, false, false, false, "SpellToInterrupt") return end
					elseif GS.Spec == 2 or GS.Spec == 3 then
						if GS.SIR(106839) then GS.Cast("target", 106839, false, false, false, "SpellToInterrupt") return end
					end
				elseif GSR.Class == "WARLOCK" then
					if GS.PlayerHasTalent(5, 1) then
						if GS.SCA(119911, "target", interruptCasting) then GS.Cast("target", 119911, false, false, false, "SpellToInterrupt") return end
					elseif GS.Aura("player", 108503) then
						if GS.SIR(132409) then GS.Cast("target", 132409, false, false, false, "SpellToInterrupt") return end
					else
						if GS.SCA(19647, "target", interruptCasting) then GS.Cast("target", 19647, false, false, false, "SpellToInterrupt") return end
					end
				end
			end
		end
	end

	function GS.Taunt() -- keep updated: implement more bosses for taunt @tanking @WoD
		if not UnitExists("focus") or not UnitExists("target") or UnitThreatSituation("player", "target") > 1 then return end
		if UnitName("target") == "The Butcher" and GS.AuraStacks("focus", 156151, --[[try 3?]]2) and not GS.Aura("player", 156151) then -- keep updated: see what the common strategy is @tanking @WoD
			GS.Cast("target", GS.TauntID[GSR.Class], false, false, false, "SpellToInterrupt")
			return
		elseif UnitName("target") == "Brackenspore" and GS.AuraStacks("focus", 163241, 4) and not GS.Aura("player", 163241) then
			GS.Cast("target", GS.TauntID[GSR.Class], false, false, false, "SpellToInterrupt")
			return
		elseif UnitName("target") == "Ko'ragh" and GS.Aura("focus", 162186) and not GS.Aura("player", 162186) then
			GS.Cast("target", GS.TauntID[GSR.Class], false, false, false, "SpellToInterrupt")
			return
		end
	end

	function GS.Slowfall() -- keepupdated: falling far movement flag is way too early @notimportant
		if IsFalling() and not UnitIsDeadOrGhost("player") and bit.band(UnitMovementFlags("player"), 0x1000) ~= 0 then
			StopFalling();
			-- playerX, playerY, playerZ = ObjectPosition("player")
			-- MoveTo(playerX, playerY, playerZ-0.00000000000000000001);
		end
	end

	function GS.TimelessIsle()
		if GetCurrentMapContinent() == 6 and GetCurrentMapZone() == 10 then
			if not UnitBuff("player","Singing Crystal") and GetItemCount(103641,false,false) > 0 then UseItemByName(103641) end
			if not UnitBuff("player","Book of the Ages") and GetItemCount(103642,false,false) > 0 then UseItemByName(103642) end
			if not UnitBuff("player","Dew of Eternal Morning") and GetItemCount(103643,false,false) > 0 then UseItemByName(103643) end
			if not UnitBuff("player","Visions of Insanity") and GetItemCount(86569,false,false) > 0 and GetItemCooldown(86569) == 0 then UseItemByName(86569) end
			if not UnitBuff("player","Symbiotic Growth") and GetItemCount(86580,false,false) > 0 and GetItemCooldown(86580) == 0 then UseItemByName(86580) end
		end
	end

	function GS.PlayersAlready(player)
		for k,v in pairs(GS.Players[tanksIndex].Players) do
			if tonumber(v.Player) then if v.Player == player then return false end elseif ObjectPointer("player") == player then return false end
		end
		for k,v in pairs(GS.Players[healersIndex].Players) do
			if tonumber(v.Player) then if v.Player == player then return false end elseif ObjectPointer("player") == player then return false end
		end
		for k,v in pairs(GS.Players[dpsIndex].Players) do
			if tonumber(v.Player) then if v.Player == player then return false end elseif ObjectPointer("player") == player then return false end
		end
		for k,v in pairs(GS.Players) do
			if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
				if tonumber(v.Player) then if v.Player == player then return false end elseif ObjectPointer("player") == player then return false end
			end
		end
		return true
	end

-- Bread
	function GS.ValidTarget(target, unit)
		if UnitExists("target")
		and UnitCanAttack("player", "target")
		and not UnitIsDead("target")
		then
			return true
		else
			return false
		end
	end

	function GS.Combat(unit) -- keep updated: is this even needed anymore @useless?
		if not unit then unit = "player" end
		return UnitAffectingCombat(unit)
	end

	function GS.SpellCDDuration(spell, max)
		local start, duration = GetSpellCooldown(spell)
		if max then
			return GetSpellBaseCooldown(spell)*.001 -- fix me : not working right to say the least, doesn't take into consideration (haste for paladins?) skills that affect the base skill @framework @useless?
		elseif start == 0 then
			return 0
		else
			return (start + duration - GetTime())
		end
	end

	function GS.IsCAOCH(unit)
		if not unit then unit = "player" end
		if UnitExists(unit) and (UnitCastingInfo(unit) or UnitChannelInfo(unit)) then return true else return false end
	end

	function GS.SCA(spell, unit, casting)
		if not unit then unit = "target" end
		if string.sub(unit, 1, 6) == "Player" then unit = ObjectPointer("player") end
		if GS.SIR(spell)
		and (GS.InRange(spell, unit) or UnitName(unit) == "Al'Akir") -- fixme: inrange needs an overhaul in the distant future, example Al'Akir @framework @notimportant
		and (not GS.IsCAOCH("player") or casting)
		and (select(4, GetSpellInfo(spell)) == 0 or not IsPlayerMoving() or not GS.AuraRemaining("player", 172106, (select(4, GetSpellInfo(spell))*0.001)) or not GS.AuraRemaining("player", 108839, (select(4, GetSpellInfo(spell))*0.001)) or not GS.AuraRemaining("player", 137587, (select(4, GetSpellInfo(spell))*0.001)) or not GS.AuraRemaining("player", 79206, (select(4, GetSpellInfo(spell))*0.001))) -- keep udpated: test this
		and (not GSR.Thok or ThokThrottle < GetTime() --[[or select(4, GetSpellInfo(spell)) == 0 ]]or ThokThrottle > GetTime()+(select(4, GetSpellInfo(spell))*0.001))
		-- and GS.LOS(unit) -- fixme: LOS @framework
		then
			return true
		else
			return false
		end
	end

	function GS.SIR(spell)
		if GS.SpellCDDuration(spell) <= 0
		and GS.SpellIsUsable(spell)
		and (not GSR.Thok or ThokThrottle < GetTime() or select(4, GetSpellInfo(spell)) == 0 or ThokThrottle > GetTime()+(select(4, GetSpellInfo(spell))*0.001)) -- keepupdated: test this with Pol
		then
			return true
		else
			return false
		end
	end

	function GS.SpellIsUsable(spell)
		local isUsable, notEnoughMana = IsUsableSpell(spell)
		if isUsable
		and not notEnoughMana
		then
			return true
		else
			return false
		end
	end

	function GS.PoolCheck(spell)
		local isUsable, notEnoughMana = IsUsableSpell(spell)
		if GS.SpellCDDuration(spell, nil) <= 0
		and not isUsable
		and notEnoughMana
		then
			return true
		else
			return false
		end
	end

	function GS.InRange(spell, unit)
		if not unit then unit = "target" end

		if tonumber(spell) then spelltext = GetSpellInfo(spell) end

		if UnitExists(unit) and GS.Health(unit) > 0 then

			local inRange = IsSpellInRange(spelltext, unit)

			if inRange == 1 then
				return true
			elseif inRange == 0 then
				return false
			elseif FindSpellBookSlotBySpellID(spell) then
				return IsSpellInRange(FindSpellBookSlotBySpellID(spell), "spell", unit) == 1
			elseif tContains(GS.tblInRange, spelltext) then
				for i = 1, #GS.tblInRange do
					if GS.tblInRange[i] == spelltext then
						return GS.Distance(unit, nil) <= GS.listInRange[i]
					end
				end
			else
				for i = 1, 200 do
					if GetSpellBookItemName(i, "spell") == spelltext then return IsSpellInRange(i, "spell", unit) == 1 end
				end
			end
		end
	end

	function GS.Aura(guid, ...) -- Example GS.Aura("target", 1234, "", "PLAYER") everything past the 1st extra argument is not required
		local a = {...}

		if type(a[1]) == "number" then a[1] = GetSpellInfo(a[1]) end
		if type(guid) == "string" and string.sub(guid, 1, 6) == "Player" then guid = "player" end

		if UnitBuff(guid, unpack(a)) then return UnitBuff(guid, unpack(a)) elseif UnitDebuff(guid, unpack(a)) then return UnitDebuff(guid, unpack(a)) else return UnitAura(guid, unpack(a)) end -- FH GUID
	end

	function GS.AuraRemaining(unit, buff, time, ...) -- ... is the same as above, this cheks for <= the time argument if you want greater than, than do "not GS.AuraRemaining", this will return true if the aura isn't there
		if type(unit) == "string" and string.sub(unit, 1, 6) == "Player" then unit = "player" end
		if UnitExists(unit) then
			if tonumber(buff) then buff = GetSpellInfo(buff) end
			local name, _, _, _, _, _, expires = GS.Aura(unit, buff, ...)
			if not name then return true end
			if (expires-GetTime()) <= time then
				return true
			else
				return false
			end
		end
	end

	function GS.AuraStacks(unit, buff, stacks, ...) -- ... is the same as above, this checks for >= stacks argument, if you want less than, than do "not GS.AuraStacks", this will return false if the aura isn't there
		if type(unit) == "string" and string.sub(unit, 1, 6) == "Player" then unit = "player" end
		if UnitExists(unit) then
			if tonumber(buff) then buff = GetSpellInfo(buff) end
			local name, _, _, count = GS.Aura(unit, buff, ...)
			if not name then return false end
			if count >= stacks then
				return true
			else
				return false
			end
		end
	end

	function GS.PP(max) -- returns energy for Rogue and ferals, if you pass true as argument it'll return max instead of current
		local vPower = nil
		if GSR.Class == "WARRIOR" then vPower = 1 end
		if GSR.Class == "HUNTER" then vPower = 2 end
		if GSR.Class == "ROGUE" then vPower = 3 end
		if GSR.Class == "DEATHKNIGHT" then vPower = 6 end
		if GSR.Class == "WARLOCK" and GS.Spec == 1 then vPower = 7 end
		if GSR.Class == "WARLOCK" and GS.Spec == 2 then vPower = 15 end
		if GSR.Class == "WARLOCK" and GS.Spec == 3 and not max then return UnitPower("player", 14, true) elseif GSR.Class == "WARLOCK" and GS.Spec == 3 then return UnitPower("player", 14, true) end
		if GSR.Class == "PALADIN" then vPower = 9 end
		if GSR.Class == "MONK" then vPower = 12 end
		if GSR.Class == "PRIEST" and GS.Spec == 3 then vPower = 13 end
		if GSR.Class == "DRUID" and GS.Spec == 3 then vPower = 1 end
		if GSR.Class == "DRUID" and GS.Spec == 2 then vPower = 3 end
		if GSR.Class == "DRUID" and GS.Spec == 1 then vPower = 8 end
		if vPower ~= nil and not max then return UnitPower("player", vPower) elseif vPower ~= nil then return UnitPowerMax("player", vPower) end
	end

	function GS.PM() return UnitPower("player")/UnitPowerMax("player")*100 end -- return percentage of mana or default power

	function GS.UnitIsBoss(unit) -- checks the defined boss list
		if UnitExists(unit) then
			if tContains(GS.BossList, UnitName(unit)) then
				return true
			else
				return false
			end
		else
			return false
		end
	end

	function GS.PlayerHasTalent(tier, column) -- checks to see if you have the talent in your active spec
		return select(4,GetTalentInfo(tier, column, GetActiveSpecGroup()))
	end

	function GS.ChainManager(guid, Name, x, y, z, interrupt)
		if type(Name) == "number" then Name = GetSpellInfo(Name) end
		if not UnitChannelInfo("player") then
			if interruptChannel ~= false then interruptChannel = false end
			if UnitCastingInfo("player") then
				local spell = UnitCastingInfo("player")
				if type(interrupt) == "string" and interrupt ~= "SpellToInterrupt" then
					if spell == interrupt then SpellStopCasting() end
				elseif type(interrupt) == "table" then
					if tContains(interrupt, spell) then SpellStopCasting() end
				elseif interrupt ~= "SpellToInterrupt" and interrupt ~= nil then
					return
				end
			end
			if guid and UnitGUID("player") == guid then guid = "player" end

			if not guid then
				CastSpellByName(Name)
			else
				CastSpellByName(Name, guid)
			end

			if IsAoEPending() then
				if x and y and z then
					CastAtPosition(x + math.random(-0.01, 0.01), y + math.random(-0.01, 0.01), z + math.random(-0.01, 0.01))
				else
					local X, Y, Z = ObjectPosition(guid)
					CastAtPosition(X + math.random(-0.01, 0.01), Y + math.random(-0.01, 0.01), Z + math.random(-0.01, 0.01))
				end
				CancelPendingSpell()
			end
			-- debug stuff
			GS.DebugStack = debugstack(3, 100, 100)
			GS.CastDebug.guid = guid
			if guid then GS.CastDebug.nameOfMob = UnitName(guid) else GS.CastDebug.nameOfMob = UnitName("target") end
			GS.CastDebug.name = Name
			GS.CastDebug.x = x
			GS.CastDebug.y = y
			GS.CastDebug.z = z
			GS.CastDebug.interrupt = interrupt
			GS.CastDebug.time = GetTime()
			-- GS.CastDebug.performance = debugprofilestop()-timedebug
			return true
		else
			local spell = UnitChannelInfo("player")
			
			if spell == "Mind Flay" and (abs(GS.Priest.MindFlayLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) <= 1 or GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1 or GS.PP() == 5 and not GS.PlayerHasTalent(7, 1)) then
				if interruptChannel == false then
					interruptChannel = math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay)-1 ~= 0 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay)-1 or true
					return
				elseif type(interruptChannel) == "number" then
					if tonumber(string.match(debugstack(3, 100, 100), "%d+")) < GS.Priest.MindFlayLine and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay) <= interruptChannel then SpellStopCasting() end
				elseif type(interruptChannel) == "boolean" then
					if abs(GS.Priest.MindFlayLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) > 1 then
						return
					end
				end
			elseif spell == "Insanity" and (abs(GS.Priest.InsanityLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) <= 1 or not GS.PlayerHasTalent(7, 1) and not GS.PlayerHasTalent(7, 2) and GS.PP() == 5 or GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1) then
				if interruptChannel == false then
					interruptChannel = math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay)-1 ~= 0 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay)-1 or true
					return
				elseif type(interruptChannel) == "number" then
					if tonumber(string.match(debugstack(3, 100, 100), "%d+")) < 4474 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindFlay) <= interruptChannel then SpellStopCasting() end
				elseif type(interruptChannel) == "boolean" then
					if abs(GS.Priest.InsanityLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) > 1 then
						return
					end
				end				
			elseif spell == "Mind Sear" and (abs(GS.Priest.MindSearLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) <= 1 or not GS.PlayerHasTalent(7, 1) and not GS.PlayerHasTalent(7, 2) and GS.PP() == 5 or GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1) then
				if interruptChannel == false then
					interruptChannel = math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear)-1 ~= 0 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear)-1 or true
					return
				elseif type(interruptChannel) == "number" then
					if tonumber(string.match(debugstack(3, 100, 100), "%d+")) < 4554 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear) <= interruptChannel then SpellStopCasting() end
				elseif type(interruptChannel) == "boolean" then
					if abs(GS.Priest.MindSearLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) > 1 then
						return
					end
				end
			elseif spell == "Searing Insanity" and (abs(GS.Priest.SearingInsanityLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) <= 1 or GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1) then
				if interruptChannel == false then
					interruptChannel = math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear)-1 ~= 0 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear)-1 or true
					return
				elseif type(interruptChannel) == "number" then
					if tonumber(string.match(debugstack(3, 100, 100), "%d+")) < 4457 and math.ceil((select(6, UnitChannelInfo("player"))/1000-GetTime())/GS.Priest.MindSear) <= interruptChannel then SpellStopCasting() end
				elseif type(interruptChannel) == "boolean" then
					if abs(GS.Priest.SearingInsanityLine-tonumber(string.match(debugstack(3, 100, 100), "%d+"))) > 1 then
						return
					end
				end
			end
			
			if guid and UnitGUID("player") == guid then guid = "player" end

			if not guid then
				CastSpellByName(Name)
			else
				CastSpellByName(Name, guid)
			end

			if IsAoEPending() then
				if x and y and z then
					CastAtPosition(x + math.random(-0.01, 0.01), y + math.random(-0.01, 0.01), z + math.random(-0.01, 0.01))
				else
					local X, Y, Z = ObjectPosition(guid)
					CastAtPosition(X + math.random(-0.01, 0.01), Y + math.random(-0.01, 0.01), Z + math.random(-0.01, 0.01))
				end
				CancelPendingSpell()
			end
			-- debug stuff
			GS.DebugStack = debugstack(3, 100, 100)
			GS.CastDebug.guid = guid
			if guid then GS.CastDebug.nameOfMob = UnitName(guid) else GS.CastDebug.nameOfMob = UnitName("target") end
			GS.CastDebug.name = Name
			GS.CastDebug.x = x
			GS.CastDebug.y = y
			GS.CastDebug.z = z
			GS.CastDebug.interrupt = interrupt
			GS.CastDebug.time = GetTime()
			-- GS.CastDebug.performance = debugprofilestop()-timedebug
			return true
		end
	end

	function GS.Cast(guid, Name, x, y, z, interrupt) -- guid = unit, name = spellid or name, x,y,z = custom location if you want it (for aoe selection) else it'll cast at guid's position, interrupt is a string or table of strings of spells or channels you want to interrupt
		if GSR.Class == "PRIEST" and GS.Spec == 3 then
			GS.ChainManager(guid, Name, x, y, z, interrupt)
			return
		end
		if type(Name) == "number" then Name = GetSpellInfo(Name) end

		if UnitChannelInfo("player") or UnitCastingInfo("player") then
			local spell = UnitChannelInfo("player") or UnitCastingInfo("player")
			if type(interrupt) == "string" and interrupt ~= "SpellToInterrupt" then
				if spell == interrupt then SpellStopCasting() end
			elseif type(interrupt) == "table" then
				if tContains(interrupt, spell) then SpellStopCasting() end
			elseif interrupt ~= "SpellToInterrupt" and interrupt ~= nil then
				return
			end
		end
		if guid and UnitGUID("player") == guid then guid = "player" end

		if not guid then
			CastSpellByName(Name)
		else
			CastSpellByName(Name, guid)
		end

		if IsAoEPending() then
			if x and y and z then
				CastAtPosition(x + math.random(-0.01, 0.01), y + math.random(-0.01, 0.01), z + math.random(-0.01, 0.01))
			else
				local X, Y, Z = ObjectPosition(guid)
				CastAtPosition(X + math.random(-0.01, 0.01), Y + math.random(-0.01, 0.01), Z + math.random(-0.01, 0.01))
			end
			CancelPendingSpell()
		end
		-- debug stuff
		GS.DebugStack = debugstack(2, 100, 100)
		GS.CastDebug.guid = guid
		if guid then GS.CastDebug.nameOfMob = UnitName(guid) else GS.CastDebug.nameOfMob = UnitName("target") end
		GS.CastDebug.name = Name
		GS.CastDebug.x = x
		GS.CastDebug.y = y
		GS.CastDebug.z = z
		GS.CastDebug.interrupt = interrupt
		GS.CastDebug.time = GetTime()
		-- GS.CastDebug.performance = debugprofilestop()-timedebug
		return true
	end

	function GS.Distance(target, base) -- compares distance between two objects if base == nil than base = player
		local X1, Y1, Z1 = ObjectPosition(target)
		local X2, Y2, Z2 = nil, nil, nil
		if not base then X2, Y2, Z2 = ObjectPosition("player") else X2, Y2, Z2 = ObjectPosition(base) end

		return math.sqrt(((X2 - X1) ^ 2) + ((Y2 - Y1) ^ 2) + ((Z2 - Z1) ^ 2))
	end

	function GS.CombatReach(guid) return UnitCombatReach(guid) end

	function GS.Health(guid, max, percent) -- returns the units max health if max is true, percentage remaining if percent is true and max is false, or current health
		if max then
			return UnitHealthMax(guid)
		elseif percent then
			return UnitHealth(guid)/UnitHealthMax(guid)*100
		else
			return UnitHealth(guid)
		end
	end

	function GS.PlayerCount(yards, tapped)
		if not GS.Throttle.tPlayerCount or (GetTime()-GS.Throttle.tPlayerCount) > 0.25 then
			local GMobCount = 0

			for i = 1, #GS.Targets do if UnitExists(GS.Targets[i]) and GS.Distance(GS.Targets[i]) <= yards+GS.CombatReach(GS.Targets[i]) and (UnitIsTappedByPlayer(GS.Targets[i]) or not tapped) then GMobCount = GMobCount + 1 end end

			GS.Throttle.tPlayerCount = GetTime()
			GS.Throttle.nPlayerCount = GMobCount

			return GMobCount
		elseif GS.Throttle.nPlayerCount then
			return GS.Throttle.nPlayerCount
		else
			return 0
		end
	end

	function GS.TargetCount(yards, tapped)

		if not UnitExists("target") or UnitHealth("target") == 0 then return 0 end

		if GetTime()-GS.Throttle.tTargetCount > 0.25 then

			local GMobCount = 0

			for i = 1, #GS.Targets do
				if UnitExists(GS.Targets[i]) and GS.Distance(GS.Targets[i], "target") <= yards+GS.CombatReach(GS.Targets[i]) and (UnitIsTappedByPlayer(GS.Targets[i]) or not tapped) then
					GMobCount = GMobCount + 1
				end
			end

			GS.Throttle.tTargetCount = GetTime()
			GS.Throttle.nTargetCount = GMobCount

			if GMobCount then
				if GMobCount == 0 then return 1 end
				return GMobCount
			end
		elseif GS.Throttle.nTargetCount then
			if GS.Throttle.nTargetCount == 0 then return 1 end
			return GS.Throttle.nTargetCount
		else
			return 1
		end
	end

	function GS.PlayerHasGlyph(id)
		for i = 1, 6 do
			local _, _, _, glyphSpell = GetGlyphSocketInfo(i)
			if glyphSpell == id then return true end
		end
		return false
	end

	function GS.PetDistance(unit, distance) if GS.Distance(unit, ObjectPointer("pet")) <= distance+GS.CombatReach(unit) then return true else return false end end

	function GS.Face(guid) -- ripped from ccR
		local X1, Y1 = ObjectPosition("player")
		local X2, Y2 = ObjectPosition(guid)
		local Angle = rad(atan2(Y2 - Y1, X2 - X1))
		local IsExactFacing = abs(ObjectFacing("player") - Angle) < 0.1
		if not IsExactFacing then
		   local pX, pY = ObjectPosition("player")
		   local tX, tY = ObjectPosition(guid)
		   FaceDirection(math.atan2(tY - pY, tX - pX) % (math.pi * 2))
		end
	end

	function GS.LOS(guid, other, increase)
		other = other or "player"
		local X1, Y1, Z1 = ObjectPosition(guid)
		local X2, Y2, Z2 = ObjectPosition(other)
		return not TraceLine(X1, Y1, Z1  + (increase or 2), X2, Y2, Z2 + (increase or 2), bit.bor(0x1, 0x10, 0x100, 0x20000));
	end

	function GS.PullEnemies(reach, tapped) -- gets enemies in an AoE
		if #GS.Targets == 0 then return {} end
		local units = {}
		for i = 1, #GS.Targets do
			if UnitExists(GS.Targets[i]) then
				if GS.Distance(GS.Targets[i]) <= reach and (not tapped or UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) then
					table.insert(units, GS.Targets[i])
				end
			end
		end
		return units
	end

	function GS.SmartAoE(reach, size, tapped, tableX) -- smart aoe placement credits to phelps a.k.a doc|brown
		local units = GS.PullEnemies(reach, tapped)
		local win = 0
		local winners = {}
		for _, enemy in ipairs(units) do
			local neighbors = 0
			for _, neighbor in ipairs(units) do
				if GS.Distance(enemy, neighbor) <= size then
					neighbors = neighbors + 1
				end
			end
			if neighbors >= win and neighbors > 0 then
				table.insert(winners, enemy)
				win = neighbors
			end
		end
		-- if tableX then return winners end
		return GS.AvgPosObjects(winners)
	end -- use it like this: GS.Cast(nil, 104232, GSmartAoE(35, 8))

	function GS.AvgPosObjects (table) -- FH GUID
		local Total = #table;
		local X, Y, Z = 0, 0, 0;

		for Key, ThisObject in pairs(table) do
			if ThisObject then
				local ThisX, ThisY, ThisZ = ObjectPosition(ThisObject);
				if ThisX and ThisY then
					X = X + ThisX;
					Y = Y + ThisY;
					Z = Z + ThisZ;
				end
			end
		end

		X = X / Total;
		Y = Y / Total;
		Z = Z / Total;
		return X, Y, Z;
	end

	function GS.TierBonus(version)
		local tierid = GS.Tier[""..GSR.Class..""][""..version..""]
		local SetNumber = 0
		local headid = GetInventoryItemID("player", 1)
		local shoulderid = GetInventoryItemID("player", 3)
		local chestid = GetInventoryItemID("player", 5)
		local legsid = GetInventoryItemID("player", 7)
		local handsid = GetInventoryItemID("player", 10)

		for i, v in pairs(tierid) do
			if headid == v or shoulderid == v or chestid == v or legsid == v or handsid == v then
				SetNumber = SetNumber + 1
			end
		end

		return SetNumber
	end

	GS.Trinkets.Int = {
		110002, -- fleshrender's meathook
		110003, -- ragewing's firefang
		110004, -- coagulated genesaur blood
		111227, -- primal gladiator's badge of dominance horde
		112320, -- sandman's pouch
		113835, -- shards of nothing
		113948, -- darmac's unstable talisman
		113984, -- blackiron micro crucible
		114489, -- turbulent focusing crystal
		115754, -- primal gladiator's badge of dominance alliance
		116315, -- Furyheart Talisman
		118878, -- copeland's clarity
		119194, -- goren soul repository
	}
	GS.Trinkets.Agi ={
		114488, -- turbulent vial of toxin
		114427, -- munificent emblem of terror
		114366, -- tormented tooth of ferocity
		115749, -- primal gladiator's badge of conquest (alliance)
		111222, -- primal gladiator's badge of conquest (horde)
		109999, -- witherbark's branch
		109998, -- gor'ashan's lodestone spike
		109997, -- kihra's adrenaline injector
		116314, -- blackheart enforcer's medallion
		113612, -- scales of doom
		113931, -- beating heart of the mountain
		113985, -- humming blackiron trigger
		118114, -- meaty dragonspike trophy
		118876, -- lucky double-sided coin
	}
	GS.Trinkets.Str = {
		111232, -- primal gladiator's badge of victory (horde)
		115759, -- primal gladiator's badge of victory (alliance)
		110013, -- emberscale talisman
		110012, -- bonemaw's big toe
		110014, -- spores of alacrity
		118882, -- scabbard of kyanos
		113645, -- tectus' beating heart
		113969, -- vial of convulsive shadows
		119193, -- horn of screaming spirits
		113983, -- forgemaster's insignia
	}

	GS.Trinkets.Procs = {}

	GS.Trinkets.Procs.Int = {
		126683, -- call of dominance (primal gladiator's badge of dominance)
	}
	GS.Trinkets.Procs.SPower = {
		177594, -- (copeland's clarity)
	}
	GS.Trinkets.Procs.Agi = {
		126990, -- call of conquest (primal gladiator's badge of conquest)
		177597, -- "lucky" flip (lucky double-sided coin)
	}
	GS.Trinkets.Procs.Str = {
		126679, -- call of victory (primal gladiator's badge of victory)
		177189, -- sword technique (scabbard of kyanos)
	}

	GS.Trinkets.Procs.Haste = {
		--// int
		176882, -- turbulent focusing crystal
		176875, -- void shards (shards of nothing)
		176980, -- heart of the fury (furyheart talisman)
		177051, -- instability (darmac's unstable talisman)

		--// agi
		176883, -- turbulent vial of toxin
		177035, -- meaty dragonspine trophy

		--// int and agi
		165531, -- haste (fleshrender's meathook, tormented tooth of ferocity)

		--// agi and str
		165822, -- haste (witherbark's branch, spores of alacrity)
	}
	GS.Trinkets.Procs.Multi = {
		--// int
		165832, -- coagulated genesaur blood

		--// agi
		165542, -- multi-strike (gor'ashan's lodestone spike)
		176984, -- blackheart enforcer's medallion
		177038, -- balanced fate (scales of doom)
		176878, -- lub-dub (beating heart of the mountain)

		--// str
		176874, -- convulsive shadows (vial of convulsive shados)
	}
	GS.Trinkets.Procs.Crit = {
		--// int
		162919, -- Nightmare Fire (Sandman's Pouch)
		177046, -- howling soul (goren soul repository)

		--// agi
		165830, -- critical strike (munificent emblem of terror)

		--// str
		177040, -- tectus' heartbeat (tectus' beating heart)

		--// str and healer
		165532, -- critical strike(bonemaw's big toe, voidmender's shadowgem)
	}
	GS.Trinkets.Procs.Versa = {
		--// int and str and tank
		165543, -- versatility (ragewing's firefang, emberscale talisman, tormented seal of fortitude)
	}
	GS.Trinkets.Procs.Mastery = {
		--//str
		177042, -- screaming spirits (horn of screaming spirits)
		--// agi and str
		165485, -- mastery (kihra's adrenaline injector, tormented fang of gore)
	}

	GS.Trinkets.Stacking = {}
	GS.Trinkets.Stacking.Multi = {
		--// int
		177081, -- molten metal (blackiron micro crucible)

		--// str
		177096, -- forgemaster's vigor (forgemaster's insignia)
	}
	GS.Trinkets.Stacking.Crit = {
		177067, -- detonation (humming blackiron trigger)
	}

	function GS.Trinket(role, any, remainingTime, remainingInverse, proc)
		if role == "str" then
		elseif role == "agi" then
		elseif role == "int" then
			if any == "active" then
				for k,v in pairs(GS.Trinkets.Procs) do
					for c,b in pairs(GS.Trinkets.Procs[k]) do
						if GS.Aura("player", b) then return true end
					end
				end
				return false
			elseif any == "remaining" then
				if not proc then
					for k,v in pairs(GS.Trinkets.Procs) do
						for c,b in pairs(GS.Trinkets.Procs[k]) do
							if remainingInverse then
								if GS.Aura("player", b) and not GS.AuraRemaining("player", b, remainingTime) then return true end
							else
								if GS.Aura("player", b) and GS.AuraRemaining("player", b, remainingTime) then return true end
							end
						end
					end
					return false
				elseif proc == "haste" then
					for k,v in pairs(GS.Trinkets.Procs.Haste) do
						if remainingInverse then
							if GS.Aura("player", v) and not GS.AuraRemaining("player", v, remainingTime) then return true end
						else
							if GS.Aura("player", v) and GS.AuraRemaining("player", v, remainingTime) then return true end
						end
						return false
					end
				end
			end
		end
	end

	function GS.PlayerIsBehind(GUID)
		local PlayerX, PlayerY = ObjectPosition("player");
		local X, Y, Z = ObjectPosition(GUID);
		local Rotation = ObjectFacing(GUID);

		if bit.band(ObjectType(GUID), 0x8) and UnitTarget(GUID) and UnitExists(UnitTarget(GUID)) then
			-- If the unit has a target then it's rotation will be incorrect, so we need to calculate the correct one.
			local tX, tY, tZ = ObjectPosition(UnitTarget(GUID));
			Rotation = (rad(atan2(Y - tY, X - tX)) + math.pi) % (math.pi * 2);
		end

		return ((PlayerX - X) * math.cos(-Rotation)) - ((PlayerY - Y) * math.sin(-Rotation)) < 0;
	end

	function GS.Bloodlust(remaining)
		if remaining then
			return ((GS.Aura("player", 80353) and not GS.AuraRemaining("player", 80353, remaining))
					or (GS.Aura("player", 2825) and not GS.AuraRemaining("player", 2825, remaining))
					or (GS.Aura("player", 32182) and not GS.AuraRemaining("player", 32182, remaining))
					or (GS.Aura("player", 90355) and not GS.AuraRemaining("player", 90355, remaining))
					or (GS.Aura("player", 160452) and not GS.AuraRemaining("player", 160452, remaining))
					or (GS.Aura("player", 146555) and not GS.AuraRemaining("player", 146555, remaining))
					or (GS.Aura("player", 178207) and not GS.AuraRemaining("player", 178207, remaining)))
		end
		if GS.Aura("player", 80353) or GS.Aura("player", 2825) or GS.Aura("player", 32182) or GS.Aura("player", 90355) or GS.Aura("player", 160452) or GS.Aura("player", 146555) or GS.Aura("player", 178207) then
			return true
		else
			return false
		end
	end

	-- Credits to StinkyTwitch
	function GS.HRotation()
		FaceDirection(mod(ObjectFacing("Player") + math.pi, math.pi * 2))
	end
	-- Credits to StinkyTwitch

	-- RIPPED FROM ccR
	function GS.IsFacing(unit, other)
		local X, Y, Z = ObjectPosition(unit);
		local Rotation = ObjectFacing(unit);
		local OtherX, OtherY = ObjectPosition(other)
		return ((X - OtherX) * math.cos(-Rotation)) - ((Y - OtherY) * math.sin(-Rotation)) < 0
	end
	-- RIPPED FROM ccR

	-- function round(num, idp)
	--   local mult = 10^(idp or 0)
	--   return math.floor(num * mult + 0.5) / mult
	-- end

	function GS.TextBox(turn, yesno, failed)
		if failed then
			groupcomposereditbox:Hide()
			buttonyes:Hide()
			buttonno:Hide()
			button:Hide()
			groupcomposereditbox:SetFocus()
			groupcomposereditbox:SetText("GS: Failed to get version number.")
			groupcomposereditbox:SetScript("OnTextChanged", function() groupcomposereditbox:SetText("GS: Failed to get version number.") end)
			groupcomposereditbox:HighlightText()
			groupcomposereditbox:Show()
			-- buttonyes:Show()
			-- buttonno:Show()
			button:Show()
			return
		end
		if yesno then
			groupcomposereditbox:Hide()
			buttonyes:Hide()
			buttonno:Hide()
			button:Hide()
			groupcomposereditbox:SetFocus()
			if not turn then
				buttonyes:SetScript("OnClick", function(self)
					groupcomposereditbox:Hide()
					OpenURL("https://code.google.com/p/gstar/wiki/Changelog")
					buttonyes:Hide()
					buttonno:Hide()
				end)
				buttonno:SetScript("OnClick", function(self)
					groupcomposereditbox:Hide()
					buttonyes:Hide()
					buttonno:Hide()
				end)

				groupcomposereditbox:SetText("GS: There's an update. Open changelog?")
				groupcomposereditbox:SetScript("OnTextChanged", function() groupcomposereditbox:SetText("GS: There's an update. Open changelog?") end)
			elseif turn == "tutorial" then
				buttonyes:SetScript("OnClick", function(self)
					groupcomposereditbox:Hide()
					-- OpenURL("https://code.google.com/p/gstar/wiki/Changelog")
					buttonyes:Hide()
					buttonno:Hide()
					GS.Tutorial()
				end)
				buttonno:SetScript("OnClick", function(self)
					groupcomposereditbox:Hide()
					buttonyes:Hide()
					buttonno:Hide()
					GSR.TutorialRun = false
				end)

				groupcomposereditbox:SetText("GS: Would you like to run the tutorial?")
				groupcomposereditbox:SetScript("OnTextChanged", function() groupcomposereditbox:SetText("GS: Would you like to run the tutorial?") end)
			end
			groupcomposereditbox:HighlightText()
			groupcomposereditbox:Show()
			buttonyes:Show()
			buttonno:Show()
			return
		end
		if turn then
			groupcomposereditbox:Hide()
			buttonyes:Hide()
			buttonno:Hide()
			button:Hide()
			groupcomposereditbox:SetFocus()
			groupcomposereditbox:SetText(turn)
			groupcomposereditbox:SetScript("OnTextChanged", function() groupcomposereditbox:SetText(""..turn.."") end)
			groupcomposereditbox:HighlightText()
			groupcomposereditbox:Show()
			button:Show()
			return
		end
		GroupComposerFrameCheck = true
		groupcomposereditbox = CreateFrame("EditBox", nil, WorldFrame)
		groupcomposereditboxLeft = groupcomposereditbox:CreateTexture(nil, "BACKGROUND")
		groupcomposereditboxRight = groupcomposereditbox:CreateTexture(nil, "BACKGROUND")
		groupcomposereditboxMiddle = groupcomposereditbox:CreateTexture(nil, "BACKGROUND")
		do
			groupcomposereditboxLeft:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Left")
			groupcomposereditboxLeft:SetHeight(32)
			groupcomposereditboxLeft:SetWidth(64)
			groupcomposereditboxLeft:SetPoint("LEFT", -14, 0)
			groupcomposereditboxLeft:SetTexCoord(0, 0.125, 0, 1)
			groupcomposereditboxRight:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
			groupcomposereditboxRight:SetHeight(32)
			groupcomposereditboxRight:SetWidth(64)
			groupcomposereditboxRight:SetPoint("RIGHT", 6, 0)
			groupcomposereditboxRight:SetTexCoord(0.875, 1, 0, 1)
			groupcomposereditboxMiddle:SetTexture("Interface\\ChatFrame\\UI-ChatInputBorder-Right")
			groupcomposereditboxMiddle:SetHeight(32)
			groupcomposereditboxMiddle:SetWidth(1)
			groupcomposereditboxMiddle:SetPoint("LEFT", groupcomposereditboxLeft, "RIGHT")
			groupcomposereditboxMiddle:SetPoint("RIGHT", groupcomposereditboxRight, "LEFT")
			groupcomposereditboxMiddle:SetTexCoord(0, 0.9375, 0, 1)
		end
		groupcomposereditbox:SetHeight(32)
		groupcomposereditbox:SetWidth(250)
		groupcomposereditbox:SetPoint("TOP", 0, -16)
		groupcomposereditbox:SetFontObject("GameFontHighlight")
		groupcomposereditbox:SetTextInsets(0, 0, 0, 1)
		groupcomposereditbox:SetFocus()
		groupcomposereditbox:HighlightText()

		buttonyes = CreateFrame("Button", nil, groupcomposereditbox)
		buttonyes:SetHeight(24)
		buttonyes:SetWidth(75)
		buttonyes:SetPoint("BOTTOMLEFT", 0, -20)
		buttonyes:SetNormalFontObject("GameFontNormal")
		buttonyes:SetHighlightFontObject("GameFontHighlight")
		buttonyes:SetNormalTexture(buttonyes:CreateTexture(nil, nil, "UIPanelButtonUpTexture"))
		buttonyes:SetPushedTexture(buttonyes:CreateTexture(nil, nil, "UIPanelButtonDownTexture"))
		buttonyes:SetHighlightTexture(buttonyes:CreateTexture(nil, nil, "UIPanelButtonHighlightTexture"))
		buttonyes:SetText(YES)

		buttonno = CreateFrame("Button", nil, groupcomposereditbox)
		buttonno:SetHeight(24)
		buttonno:SetWidth(75)
		buttonno:SetPoint("BOTTOMRIGHT", 0, -20)
		buttonno:SetNormalFontObject("GameFontNormal")
		buttonno:SetHighlightFontObject("GameFontHighlight")
		buttonno:SetNormalTexture(buttonno:CreateTexture(nil, nil, "UIPanelButtonUpTexture"))
		buttonno:SetPushedTexture(buttonno:CreateTexture(nil, nil, "UIPanelButtonDownTexture"))
		buttonno:SetHighlightTexture(buttonno:CreateTexture(nil, nil, "UIPanelButtonHighlightTexture"))
		buttonno:SetText(NO)

		-- buttonyes:SetScript("OnClick", function(self)
		-- groupcomposereditbox:Hide()
		-- OpenURL("https://code.google.com/p/gstar/wiki/Changelog")
		-- buttonyes:Hide()
		-- buttonno:Hide()
		-- end)
		-- buttonno:SetScript("OnClick", function(self)
		-- groupcomposereditbox:Hide()
		-- buttonyes:Hide()
		-- buttonno:Hide()
		-- end)

		button = CreateFrame("Button", nil, groupcomposereditbox)
		button:SetHeight(24)
		button:SetWidth(75)
		button:SetPoint("BOTTOM", 0, -20)
		button:SetNormalFontObject("GameFontNormal")
		button:SetHighlightFontObject("GameFontHighlight")
		button:SetNormalTexture(button:CreateTexture(nil, nil, "UIPanelButtonUpTexture"))
		button:SetPushedTexture(button:CreateTexture(nil, nil, "UIPanelButtonDownTexture"))
		button:SetHighlightTexture(button:CreateTexture(nil, nil, "UIPanelButtonHighlightTexture"))
		button:SetText(OKAY)
		button:Show()
		button:SetScript("OnClick", function(self)
			groupcomposereditbox:Hide()
			button:Hide()
			end)
		groupcomposereditbox:Hide()
		buttonyes:Hide()
		buttonno:Hide()
		button:Hide()
	end

	function GS.RuneCheck(slot, table)
		if string.lower(slot) == "slot" then
			local blood, frost, unholy = 0, 0, 0
			local runetype
			for i = 1, 6 do
				if GetRuneCount(i) == 1 then
					if i == 1 or i == 2 then
						blood = blood + 1
					elseif i == 3 or i == 4 then
						unholy = unholy + 1
					elseif i == 5 or i == 6 then
						frost = frost + 1
					end
				end
			end
			return blood, frost, unholy
		elseif string.lower(slot) == "available" then
			local a = 0
			if table == "Blood" then
				for i = 1, 6 do
					if GetRuneCount(i) == 1 then
						if i == 1 or i == 2 then
							a = a + 1
						else
							if GetRuneType(i) == 4 then
								a = a + 1
							end
						end
					end
				end
			elseif table == "Frost" then
				for i = 1, 6 do
					if GetRuneCount(i) == 1 then
						if i == 5 or i == 6 then
							a = a + 1
						else
							if GetRuneType(i) == 4 then
								a = a + 1
							end
						end
					end
				end
			elseif table == "Unholy" then
				for i = 1, 6 do
					if GetRuneCount(i) == 1 then
						if i == 3 or i == 4 then
							a = a + 1
						else
							if GetRuneType(i) == 4 then
								a = a + 1
							end
						end
					end
				end
			end
			return a
		elseif string.lower(slot) == "onlydeath" then
			local a = 0
			if table == "Blood" then
				for i = 1, 2 do
					if GetRuneCount(i) == 1 and GetRuneType(i) == 4 then
						a = a + 1
					end
				end
			elseif table == "Frost" then
				for i = 5, 6 do
					if GetRuneCount(i) == 1 and GetRuneType(i) == 4 then
						a = a + 1
					end
				end
			elseif table == "Unholy" then
				for i = 3, 4 do
					if GetRuneCount(i) == 1 and GetRuneType(i) == 4 then
						a = a + 1
					end
				end
			end
			return a
		end
	end

	-- NOT ACTUALLY MY SHIT FORGOT WHO THIS WAS
	-- DEATHKNIGHT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	-- blood, frost, unholy, death = GetRunes()
	--	@return
	-- 	    blood - Number of ready blood runes. [0-2] (number)
	-- 	    frost - Number of ready frost runes. [0-2] (number)
	-- 	    unholy - Number of ready unholy runes. [0-2] (number)
	-- 	    death   - Number of ready death runes. [0-2] (number)
	function GS.Runes()

		local blood, frost, unholy, death = 0,0,0,0
		local type
		for i=1,6 do
			type = GetRuneType(i)
			if  select(3, GetRuneCooldown(i)) then -- ready
				if type == 1 then
					blood = blood + 1
				elseif type == 2 then
					unholy = unholy + 1
				elseif type == 3 then
					frost = frost + 1
				elseif type == 4 then
					death = death + 1
				end
			end
		end
		return blood, frost, unholy, death
	end
	-- depleted = GetDepletedRunes()
	--        @return depleted        - number of fully delpleted runes [0-3] (number)
	function GS.DepletedRunes()

		local regenThreshold  = 1
		local depleted = 0
		for i=1,6,2 do
			local start, duration, runeReady = GetRuneCooldown(i)
			local start2, duration2, runeReady2 = GetRuneCooldown(i+1)
			if not runeReady and not runeReady2 and duration > 0 and duration2 > 0 and start > 0 and start2 > 0 then
				if (start-GetTime()+duration)>=regenThreshold and (start2-GetTime()+duration2)>=regenThreshold then
					depleted = depleted + 1
				end
			end
		end
		return depleted
	end

	function GS.Resolve()
		GSSpells:ClearLines()
		GSSpells:SetUnitBuff("player", "Resolve")
		local percent, damage = string.match(GSSpellsTextLeft2:GetText(), "(%d+)%%.-: (%d+)")
		return tonumber(percent), tonumber(damage)
	end

	function GS.Select(a, b, t)
		if a == "maxhealth" then
			local max, maxhp = nil, 0
			for i = 1, #GS.Targets do
				if GS.Health(GS.Targets[i]) > maxhp and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) and GS.Targets[i] ~= ObjectPointer("target") then
					if b ~= nil then
						if b() == true then max = GS.Targets[i] end
					else
						max = GS.Targets[i]
					end
				end
			end
			return max
		end
		if a == "minpercenthealth" then
			local max, maxhp = nil, math.huge
			for i = 1, #GS.Targets do
				if GS.Health(GS.Targets[i], false, true) < maxhp and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) and GS.Targets[i] ~= ObjectPointer("target") then
					max = GS.Targets[i]
				end
			end
			return max
		end
	end

-- start your engines
	GS.Initialize()

-- Rotations 
	function GS.WARRIOR1() -- arms
		if GS.Combat() then
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			GS.MultiDoT("Rend")
			if GS.ValidTarget() then
				StartAttack("target")
				-- # actions+=/use_item,slot=trinket1,if=active_enemies=1&(buff.bloodbath.up|(!talent.bloodbath.enabled&debuff.colossus_smash.up))|(active_enemies>=2&(prev_gcd.ravager|(!talent.ravager.enabled&!cooldown.bladestorm.remains&dot.rend.ticking)))
				-- if GSR.Pot and GS.CDs and (potcheck) and GS.UnitIsBoss("target") and (GS.Health("target", maxhealth, true) < 20 and GS.Aura("player", 1719) or GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 25) then end -- pot
				-- actions+=/potion,name=draenic_strength,if=(target.health.pct<20&buff.recklessness.up)|target.time_to_die<25
				if GS.CDs and GS.SIR(1719) and GS.SpellCDDuration(61304, nil) == 0 and ((GS.Aura("target", 772, "", "PLAYER") and ((GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 190) or GS.Health("target", maxhealth, true) < 20) and (not GS.PlayerHasTalent(6, 2) and (GS.Aura("player", 167105, "", "PLAYER") and (not GS.PlayerHasTalent(6, 3) or GS.SpellCDDuration(46924, nil) ~= 0)) or GS.Aura("player", 12292))) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 10)) then GS.Cast("player", 1719, nil) return end -- recklessness
				if GS.PlayerHasTalent(6, 2) and GS.CDs and GS.SIR(12292) and ((GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 20) or (GS.Aura("target", 772, "", "PLAYER") and GS.SpellCDDuration(167105, nil) < 5 and (not GS.PlayerHasTalent(7, 3) or GS.CastDebug.name == "Ravager"))) then GS.Cast("player", 12292, nil) return end -- bloodbath
				if GS.PlayerHasTalent(6, 1) and GS.CDs and GS.SIR(107574) and (GS.Aura("player", 1719) or (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 25)) then GS.Cast("player", 107574, nil) return end -- avatar
				if GS.CDs and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2) or GS.Aura("player", 1719)) then
					if GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast("target", 20572, false, false, false, "SpellToInterrupt") return end -- blood fury
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") return end -- berserking
				end
				if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(69197) and GS.PP(true)-GS.PP() > 40 then GS.Cast("target", 69197, false, false, false, "SpellToInterrupt") return end -- arcane torrent

				if GS.AoE and GS.PlayerCount(8) > 1 then
					if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(13) return end -- trinket 1
					if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(14) return end -- trinket 2
					if GS.SIR(12328) then GS.Cast("player", 12328, nil) return end -- sweeping strikes
					if GS.SCA(772) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 4 and GS.AuraRemaining("target", 772, 6, "", "PLAYER") and (GS.Health("target", maxhealth, true) > 20 or not GS.Aura("target", 167105)) then GS.Cast("target", 772, nil) return end -- rend
					if GS.AoE and GS.SIR(772) and not GS.Aura("target", 167105, "", "PLAYER") then -- rend spread
						if GS.PlayerHasTalent(3, 1) then
							for i = 1, #tRend do
								if GS.SCA(772, tRend[i], interruptCasting) and GS.TTD[tRend[i]] and GS.TTD[tRend[i]] > 8 and GS.AuraRemaining(tRend[i], 772, 6) then GS.Cast(tRend[i], 772, false, false, false, "SpellToInterrupt") return end
							end
							if #tRend < 2 then
								for i = 1, #tNoObjectRend do
									if GS.SCA(772, tNoObjectRend[i], interruptCasting) and GS.TTD[tNoObjectRend[i]] and GS.TTD[tNoObjectRend[i]] > 8 then GS.Cast(tNoObjectRend[i], 772, false, false, false, "SpellToInterrupt") return end
								end
							end
						elseif GS.PlayerCount(8) <= 8 then
							for i = 1, #tRend do
								if GS.SCA(772, tRend[i], interruptCasting) and GS.AuraRemaining(tRend[i], 772, 6) and GS.TTD[tRend[i]] and GS.TTD[tRend[i]]-(select(7, GS.Aura(tRend[i], 772, "", "PLAYER"))-GetTime()) > 18 then
									GS.Cast(tRend[i], 772, false, false, false, "SpellToInterrupt")
									return
								end
							end
							for i = 1, #tNoObjectRend do
								if GS.SCA(772, tNoObjectRend[i], interruptCasting) and GS.TTD[tNoObjectRend[i]] and GS.TTD[tNoObjectRend[i]]-(select(7, GS.Aura(tNoObjectRend[i], 772, "", "PLAYER"))-GetTime()) > 18 then
									GS.Cast(tNoObjectRend[i], 772, false, false, false, "SpellToInterrupt")
									return
								end
							end
						end
					end
					if GS.PlayerHasTalent(7, 2) and (GS.Aura("player", 12292) or GS.SpellCDDuration(167105, nil) < 4) and GS.SIR(152277) then GS.Cast("target", 152277, nil) return end -- ravager
					if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and (((GS.Aura("target", 167105, "", "PLAYER") or GS.SpellCDDuration(167105, nil) > 3) and GS.Health("target", maxhealth, true) > 20) or (GS.Health("target", maxhealth, true) < 20 and GS.PP() < 30 and GS.SpellCDDuration(167105, nil) > 4)) then GS.Cast("target", 46924, nil) return end -- bladestorm
					if GS.SCA(167105) and GS.Aura("target", 772, "", "PLAYER") then GS.Cast("target", 167105, nil) return end -- colossus smash
					if not GS.Aura("player", 52437) and GS.PlayerCount(8) <= 8 then -- execute
						if (GS.PP() > 72 and GS.SpellCDDuration(167105, nil) > (1.5/(1+GetHaste()*.01))) or GS.PP() > 80 then
							for i = 1, #GS.Targets do
								if GS.SCA(163201, GS.Targets[i], interruptCasting) then GS.Cast(GS.Targets[i], 163201, false, false, false, "SpellToInterrupt") return end
							end
						else
							for i = 1, #GS.Targets do
								if GS.SCA(163201, "target", interruptCasting) and (GS.TTD[GS.Targets[i]] and GS.TTD[GS.Targets[i]] < 5 or GS.Aura(GS.Targets[i], 167105, "", "PLAYER")) then GS.Cast(GS.Targets[i], 163201, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SCA(12294, "target", interruptCasting) and GS.Health("target", maxhealth, true) > 20 and GS.PlayerCount(8) <= 5 then GS.Cast("target", 12294, false, false, false, "SpellToInterrupt") return end -- mortal strike
					if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and not GS.Aura("target", 167105, "", "PLAYER") then GS.Cast("target", 118000, nil) return end -- dragon roar
					if GS.SIR(6343) and (GS.Health("target", maxhealth, true) > 20 or GS.PlayerCount(8) >= 9) and GS.PlayerHasGlyph(58356) then GS.Cast("target", 6343, false, false, false, "SpellToInterrupt") return end -- thunder clap
					if GS.SIR(722) and not GS.Aura("target", 167105, "", "PLAYER") and GS.PlayerCount(8) >= 9 and GS.PP() < 50 and not GS.PlayerHasTalent(3, 1) then
						for i = 1, #tRend do
							if GS.AuraRemaining(tRend[i], 772, 6) and GS.TTD[tRend[i]] and GS.TTD[tRend[i]] > 8 then GS.Cast(tRend[i], 772, false, false, false, "SpellToInterrupt") return end
						end
						for i = 1, #tNoObjectRend do
							if GS.TTD[tNoObjectRend[i]] and GS.TTD[tNoObjectRend[i]] > 8 then GS.Cast(tNoObjectRend[i], 772, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SIR(1680) and (GS.Health("target", false, true) > 20 or GS.PlayerCount(8) >= 9) then GS.Cast("target", 1680, nil) return end -- whirlwind
					if GS.PlayerHasTalent(7, 3) and GS.SCA(176289) then GS.Cast("target", 176289, nil) return end -- siegebreaker
					if GS.PlayerHasTalent(4, 1) and GS.SCA(107570) and (GS.SpellCDDuration(167105, nil) > 4 or GS.Aura("target", 167105, "", "PLAYER")) then GS.Cast("target", 107570, nil) return end -- storm bolt
					if GS.PlayerHasTalent(4, 2) and GS.SIR(46968) and GS.IsFacing("player", "target") then GS.Cast("target", 46968, nil) return end -- shockwave
					if GS.SCA(163201) and GS.Aura("player", 52437) then GS.Cast("target", 163201, nil) return end -- execute
				end

				if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and (GS.Aura("player", 12292) or (not GS.PlayerHasTalent(6, 2) and GS.Aura("target", 167105))) then UseInventoryItem(13) return end -- trinket 1
				if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and (GS.Aura("player", 12292) or (not GS.PlayerHasTalent(6, 2) and GS.Aura("target", 167105))) then UseInventoryItem(14) return end -- trinket 2
				if GS.TTD[ObjectPointer("target")] and GS.SCA(772) and GS.AuraRemaining("target", 772, 5.4, "", "PLAYER") and GS.TTD[ObjectPointer("target")] > 4 and (GS.Health("target", maxhealth, true) > 20 or not GS.Aura("target", 167105, "", "PLAYER")) then GS.Cast("target", 772, nil) return end -- rend
				if GS.PlayerHasTalent(7, 2) and GS.SpellCDDuration(167105, nil) < 4 and GS.SIR(152277) then GS.Cast("target", 152277, nil) return end -- ravager wod
				if GS.SCA(167105) then GS.Cast("target", 167105, nil) return end -- colossus smash
				if GS.SCA(12294) and GS.Health("target", false, true) > 20 then GS.Cast("target", 12294, nil) return end -- mortal strike
				if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and (((GS.Aura("target", 167105, "", "PLAYER") or GS.SpellCDDuration(167105, nil) > 3) and GS.Health("target", maxhealth, true) > 20) or (GS.Health("target", maxhealth, true) < 20 and GS.PP() < 30 and GS.SpellCDDuration(167105, nil) > 4)) then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end -- bladestorm
				if GS.PlayerHasTalent(4, 1) and GS.SCA(107570) and (GS.Health("target", maxhealth, true) > 20 or (GS.Health("target", maxhealth, true) < 20 and not GS.Aura("target", 167105, "", "PLAYER"))) then GS.Cast("target", 107570, nil) return end -- storm bolt
				if GS.PlayerHasTalent(7, 3) and GS.SCA(176289) then GS.Cast("target", 176289, nil) return end -- siegebreaker
				if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and not GS.Aura("target", 167105, "", "PLAYER") and GS.Distance("target", nil) <= 8 + UnitCombatReach("target") then GS.Cast("target", 118000, nil) return end -- dragon roar
				if GS.SCA(163201, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 163201, false, false, false, "SpellToInterrupt") return end -- execute sudden death
				if GS.SCA(163201, "target", interruptCasting) and ((not GS.Aura("player", 52437) and GS.PP() > 72 and GS.SpellCDDuration(167105, nil) > (1.5/(1+GetHaste()*.01))) or GS.Aura("target", 167105, "", "PLAYER") or (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 5)) then GS.Cast("target", 163201, false, false, false, "SpellToInterrupt") return end -- execute
				if GS.PlayerHasTalent(2, 3) and GS.SCA(103840) and GS.PP() < 40 and GS.Health("target", false, true) > 20 and GS.SpellCDDuration(167105, nil) > 1 then GS.Cast("target", 103840, nil) return end -- impending victory
				if GS.PlayerHasTalent(3, 3) then
					if GS.SCA(1464) and GS.Health("target", false, true) > 20 and (GS.PP() > 20 or GS.SpellCDDuration(167105, nil) > (1.5/(1+GetHaste()*.01))) and GS.SpellCDDuration(167105, nil) > 1 then GS.Cast("target", 1464, nil) return end -- slam
				elseif GS.Health("target", maxhealth, true) > 20 and (GS.PP() >= 40 or GS.Aura("target", 167105, "", "PLAYER")) and GS.SpellCDDuration(167105, nil) > (1.5/(1+GetHaste()*.01)) then
					if GS.SIR(6343) and GS.PlayerHasGlyph(58356) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") then GS.Cast("target", 6343, false, false, false, "SpellToInterrupt") return end -- thunder clap
					if GS.SIR(1680) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") then GS.Cast("target", 1680, nil) return end -- whirlwind
				end
				if GS.PlayerHasTalent(4, 2) and GS.SIR(46968) and GS.Distance("target", nil) <= 10 + UnitCombatReach("target") and GS.IsFacing("player", "target") then GS.Cast("target", 46968, nil) return end -- shockwave
			end
		end
	end

	function GS.WARRIOR2() -- fury
		if GetShapeshiftForm() ~= 1 then CastShapeshiftForm(1) return end -- battle stance
		if GS.Combat() then
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			if GS.ValidTarget() then
				StartAttack("target")
				if GS.SIR(18499) and (not GS.Aura("player", 12880) or (GS.PlayerHasTalent(3, 3) and not GS.Aura("player", 131116))) then GS.Cast("target", 18499, false, false, false, "SpellToInterrupt") end
				if GSR.Pot and GS.CDs and (potcheck) and GS.UnitIsBoss("target") and (GS.Health("target", maxhealth, true) < 20 and GS.Aura("player", 1719) or GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 25) then end -- pot
				-- actions+=/potion,name=draenic_strength,if=(target.health.pct<20&buff.recklessness.up)|target.time_to_die<=25

				if GS.CDs and GS.SIR(1719) and (((GS.UnitIsBoss("target") and ((GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 190) or GS.Health("target", maxhealth, true) < 20)) and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2))) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] <= 12) or GS.PlayerHasTalent(7, 1)) then GS.Cast("target", 1719, false, false, false, "SpellToInterrupt") end -- recklessness
				if GS.CDs and GS.PlayerHasTalent(6, 1) and GS.SIR(107574) and (GS.Aura("player", 1719) or (GS.TTD[ObjectPointer("target")] and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] <= 30)) then GS.Cast("target", 107574, false, false, false, "SpellToInterrupt") end
				if GS.CDs and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2) or GS.Aura("player", 1719)) then
					if GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast("target", 20572, false, false, false, "SpellToInterrupt") return end -- blood fury
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") return end -- berserking
					if GSR.Race == "BloodElf" and GS.SIR(69179) and GS.PP(true)-GS.PP() > 40 then GS.Cast("target", 69179, false, false, false, "SpellToInterrupt") return end -- arcane torrent
				end
				if GS.AoE and GS.PlayerCount(8) > 1 then
					lowestMob, maxHP = nil, math.huge
					for i = 1, #GS.Targets do
						if GS.Health(GS.Targets[i], false, false) < maxHP and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) and GS.Targets[i] ~= ObjectPointer("target") then
							lowestMob = GS.Targets[i]
							maxHP = GS.Health(GS.Targets[i], maxhealth, percenthealth)
						end
					end

					if GS.PlayerCount(8) > 3 then
						if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(13) return end -- trinket 1
						if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(14) return end -- trinket 2
						if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and GS.SpellCDDuration(61304, nil) == 0 then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") return end -- bloodbath
						if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) then GS.Cast("player", 152277, false, false, false, "SpellToInterrupt") return end -- ravager
						if GS.SCA(85288, "target", interruptCasting) and GS.Aura("player", 12880) and GS.AuraStacks("player", 85739, 3) then GS.Cast("target", 85288, false, false, false, "SpellToInterrupt") return end -- raging blow
						if GS.SCA(23881, "target", interruptCasting) and (not GS.Aura("player", 12880) or GS.PP() < 50 or not GS.Aura("player", 131116)) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SCA(85288, "target", interruptCasting) and GS.AuraStacks("player", 85739, 3) then GS.Cast("target", 85288, false, false, false, "SpellToInterrupt") return end -- raging blow
						if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and GS.Aura("player", 12880) and not GS.AuraRemaining("player", 12880, 6) then
							if GS.CDs and GS.SIR(1719) then GS.Cast("target", 1719, false, false, false, "SpellToInterrupt") end
							GS.Cast("target", 46924, false, false, false, "SpellToInterrupt")
							return
						end
						if GS.SIR(1680) then GS.Cast("target", 1680, false, false, false, "SpellToInterrupt") return end -- whirlwind dump
						if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute sd
						if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2)) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
						if GS.SCA(23881, "target", interruptCasting) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 46916) then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike bloodsurge
					end

					if GS.PlayerCount(8) == 3 then
						if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(13) return end -- trinket 1
						if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(14) return end -- trinket 2
						if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and GS.SpellCDDuration(61304, nil) == 0 then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") return end -- bloodbath
						if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) then GS.Cast("player", 152277, false, false, false, "SpellToInterrupt") return end -- ravager
						if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and GS.Aura("player", 12880) then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(23881, "target", interruptCasting) and (not GS.Aura("player", 12880) or GS.PP() < 50 or not GS.Aura("player", 131116)) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SCA(85288, "target", interruptCasting) and GS.AuraStacks("player", 85739, 2) then GS.Cast("target", 85288, false, false, false, "SpellToInterrupt") return end -- raging blow
						if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute sd
						if GS.SCA(5308, lowestMob, interruptCasting) then GS.Cast(lowestMob, 5308, false, false, false, "SpellToInterrupt") return end -- execute lowest
						if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2)) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
						if GS.SIR(1680) then GS.Cast("target", 1680, false, false, false, "SpellToInterrupt") return end -- whirlwind dump
						if GS.SCA(23881, "target", interruptCasting) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 46916) then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike bloodsurge
					end

					if GS.PlayerCount(8) == 2 then
						if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(13) return end -- trinket 1
						if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and GS.Aura("player", 152277) then UseInventoryItem(14) return end -- trinket 2
						if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and GS.SpellCDDuration(61304, nil) == 0 then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") return end -- bloodbath
						if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) then GS.Cast("player", 152277, false, false, false, "SpellToInterrupt") return end -- ravager
						if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2)) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
						if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and GS.Aura("player", 12880) then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(23881, "target", interruptCasting) and (not GS.Aura("player", 12880) or GS.PP() < 50 or not GS.Aura("player", 131116)) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SCA(5308, "target", interruptCasting) and (GS.Health("target", false, true) < 20 or GS.Aura("player", 52437)) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute sd
						if GS.SCA(5308, lowestMob, interruptCasting) then GS.Cast(lowestMob, 5308, false, false, false, "SpellToInterrupt") return end -- execute lowest
						if GS.SCA(85288, "target", interruptCasting) and GS.Aura("player", 85739) then GS.Cast("target", 85288, false, false, false, "SpellToInterrupt") return end -- raging blow
						if GS.SIR(1680) and not GS.Aura("player", 85739) then GS.Cast("target", 1680, false, false, false, "SpellToInterrupt") return end -- whirlwind dump
						if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 46916) and GS.PP() > 75 then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike bloodsurge
						if GS.SCA(23881, "target", interruptCasting) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
						if GS.SIR(1680) and GS.PP() > GS.PP(true)-20 then GS.Cast("target", 1680, false, false, false, "SpellToInterrupt") return end -- whirlwind dump
						if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 46916) then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike bloodsurge
					end
				end

				if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and (GS.Aura("player", 12292) or (not GS.PlayerHasTalent(6, 2) and (GS.Aura("player", 107574) or not GS.PlayerHasTalent(6, 1)))) then UseInventoryItem(13) return end -- trinket 1
				if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and (GS.Aura("player", 12292) or (not GS.PlayerHasTalent(6, 2) and (GS.Aura("player", 107574) or not GS.PlayerHasTalent(6, 1)))) then UseInventoryItem(14) return end -- trinket 2
				if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and GS.SpellCDDuration(61304, nil) == 0 then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") return end -- bloodbath
				if GS.SCA(100130, "target", interruptCasting) and GS.PP() > 110 and GS.Health("target", maxhealth, true) > 20 then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike
				if GS.SCA(23881, "target", interruptCasting) and (not GS.Aura("player", 12880) or (not GS.PlayerHasTalent(3, 3) and GS.PP() < 80)) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) and (GS.Aura("player", 12292) or (not GS.PlayerHasTalent(6, 2) and (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 40))) then GS.Cast("target", 152277, false, false, false, "SpellToInterrupt") return end -- ravager
				if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute sd
				if GS.PlayerHasTalent(7, 3) and GS.SCA(176289, "target", interruptCasting) then GS.Cast("target", 176289, false, false, false, "SpellToInterrupt") return end -- siegebreaker
				if GS.PlayerHasTalent(4, 1) and GS.SCA(107570, "target", interruptCasting) then GS.Cast("target", 107570, false, false, false, "SpellToInterrupt") return end -- stormbolt
				if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 46916) then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike bloodsurge
				if GS.SCA(5308, "target", interruptCasting) and (GS.Aura("player", 12880) or (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 12)) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute
				if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") and (GS.Aura("player", 12292) or not GS.PlayerHasTalent(6, 2)) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
				if GS.SCA(85288, "target", interruptCasting) then GS.Cast("target", 85288, false, false, false, "SpellToInterrupt") return end -- raging blow
				if GS.SCA(100130, "target", interruptCasting) and GS.Aura("player", 12880) and GS.Health("target", maxhealth, true) > 20 then GS.Cast("target", 100130, false, false, false, "SpellToInterrupt") return end -- wild strike
				if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end -- bladestorm
				if not GS.PlayerHasTalent(3, 3) then
					if GS.PlayerHasTalent(4, 2) and GS.SIR(46968) and GS.Distance("target", nil) <= 10+UnitCombatReach("target") and GS.IsFacing("player", "target") then GS.Cast("target", 46968, nil) return end -- shockwave
					if GS.PlayerHasTalent(2, 3) and GS.SCA(103840, "target", interruptCasting) and GS.Health("target", maxhealth, true) > 20 then GS.Cast("target", 103840, false, false, false, "SpellToInterrupt") return end -- impending victory
				end
				if GS.SCA(23881, "target", interruptCasting) then GS.Cast("target", 23881, false, false, false, "SpellToInterrupt") return end -- bloodthirst
			end
		end
	end

	function GS.WARRIOR3() -- protection
		if GS.PlayerHasTalent(7, 3) and GSR.GladStance then GS.WARRIORGLAD() return end
		if GetShapeshiftForm() ~= 2 then CastShapeshiftForm(2) return end
		if GS.Combat() then
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			GS.MultiDoT("Deep Wounds")
			if GS.ValidTarget() then
				StartAttack("target")
				if GS.CDs and (GS.Aura("player", 12292) or GS.Aura("player", 107574) or GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 10) then
					if GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 then UseInventoryItem(13) return end -- trinket 1
					if GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 then UseInventoryItem(14) return end -- trinket 2
					if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast("player", 20572, nil) return end -- blood fury
					if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end -- berserking
					if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(69197) then GS.Cast("player", 69197, nil) return end -- arcane torrent
				end
				if GS.SIR(18499) and not GS.Aura("player", 12880) then GS.Cast("target", 18499, false, false, false, "SpellToInterrupt") end -- berserker rage enrage not up

				-- actions.prot=shield_block,if=!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up)
				-- actions.prot+=/shield_barrier,if=buff.shield_barrier.down&((buff.shield_block.down&action.shield_block.charges_fractional<0.75)|rage>=85)
				-- actions.prot+=/demoralizing_shout,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)
				-- actions.prot+=/enraged_regeneration,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)
				-- actions.prot+=/shield_wall,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)
				-- actions.prot+=/last_stand,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)
				-- actions.prot+=/potion,name=draenic_armor,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)|target.time_to_die<=25
				-- actions.prot+=/stoneform,if=incoming_damage_2500ms>health.max*0.1&!(debuff.demoralizing_shout.up|buff.ravager.up|buff.shield_wall.up|buff.last_stand.up|buff.enraged_regeneration.up|buff.shield_block.up|buff.potion.up)

				if GS.AoE and GS.PlayerCount(8) > 3 then
					if GS.CDs then
						if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") return end -- blood bath
						if GS.PlayerHasTalent(6, 1) and GS.SIR(107574) then GS.Cast("target", 107574, false, false, false, "SpellToInterrupt") return end -- avatar
					end
					if GS.SIR(6343) then -- deep wounds spread
						for i = 1, #tNoObjectDeepWounds do
							if GS.Distance(tNoObjectDeepWounds[i], nil) <= 8 + UnitCombatReach(tNoObjectDeepWounds[i]) then GS.Cast("target", 6343, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(78, "target", true) and (GS.Aura("player", 122510) or GS.AuraStacks("player", 169686, 6) or GS.PP() > 110) then GS.Cast("target", 78, false, false, false, "SpellToInterrupt") return end -- heroic strike
					if GS.SCA(23922, "target", interruptCasting) and GS.Aura("player", 132404) then GS.Cast("target", 23922, false, false, false, "SpellToInterrupt") return end -- shield slam shield block
					if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) and (not GS.CDs or (not GS.PlayerHasTalent(6, 1) or (GS.Aura("player", 107574) or GS.SpellCDDuration(107574, nil) > 10))) then -- ravager
						local x, y, z = GS.SmartAoE(40, 6, true)
						GS.Cast("target", 152277, x, y, z, "SpellToInterrupt")
						return
					end
					if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and (not GS.PlayerHasTalent(6, 2) or (GS.Aura("player", 12292) or GS.SpellCDDuration(12292, nil) > 10)) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
					if GS.PlayerHasTalent(4, 2) and GS.SIR(46968) and GS.Distance("target", nil) <= 10 + UnitCombatReach("target") and GS.IsFacing("player", "target") then GS.Cast("target", 46968, nil) return end -- shockwave
					if GS.SCA(6572, "target", interruptCasting) then GS.Cast("target", 6572, false, false, false, "SpellToInterrupt") return end -- revenge
					if GS.SIR(6343) then GS.Cast("target", 6343, false, false, false, "SpellToInterrupt") return end -- thunder clap
					if GS.PlayerHasTalent(6, 3) and GS.SIR(46924) then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end -- bladestorm
					if GS.PlayerHasTalent(4, 1) and GS.SCA(107570, "target", interruptCasting) then GS.Cast("target", 107570, false, false, false, "SpellToInterrupt") return end -- storm bolt
					if GS.SCA(23922, "target", interruptCasting) then GS.Cast("target", 23922, false, false, false, "SpellToInterrupt") return end -- shield slam
					if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute with buff
					if GS.SCA(20243, "target", interruptCasting) then GS.Cast("target", 20243, false, false, false, "SpellToInterrupt") return end -- devastate
					if GS.SCA(57755, "target", interruptCasting) then GS.Cast("target", 57755, false, false, false, "SpellToInterrupt") return end -- heroic throw
					return
				end

				if GS.SCA(78, "target", true) and (GS.Aura("player", 122510) or GS.AuraStacks("player", 169686, 6)) then GS.Cast("target", 78, false, false, false, "SpellToInterrupt") end -- heroic strike
				if GS.CDs then
					if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) and (GS.PlayerHasTalent(4, 2) or (GS.PlayerHasTalent(4, 1) and GS.SpellCDDuration(107570, nil) == 0) or (GS.PlayerHasTalent(4, 3) and GS.SpellCDDuration(118000, nil) == 0)) then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") end -- bloodbath
					if GS.PlayerHasTalent(6, 1) and GS.SIR(107574) and ((not GS.PlayerHasTalent(4, 3) and not GS.PlayerHasTalent(7, 2) and not GS.PlayerHasTalent(4, 1)) or (GS.PlayerHasTalent(4, 1) and GS.SpellCDDuration(107570, nil) == 0) or (GS.PlayerHasTalent(4, 3) and GS.SpellCDDuration(118000, nil) == 0) or (GS.PlayerHasTalent(7, 2) and GS.SpellCDDuration(152277, nil) == 0)) then GS.Cast("target", 107574, false, false, false, "SpellToInterrupt") end -- avatar
				end
				if GS.SCA(23922, "target", interruptCasting) then GS.Cast("target", 23922, false, false, false, "SpellToInterrupt") return end -- shield slam
				if GS.SCA(6572, "target", interruptCasting) then GS.Cast("target", 6572, false, false, false, "SpellToInterrupt") return end -- revenge
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152277) then GS.Cast("target", 152277, false, false, false, "SpellToInterrupt") return end -- ravager
				if GS.PlayerHasTalent(4, 1) and GS.SCA(107570, "target", interruptCasting) then GS.Cast("target", 107570, false, false, false, "SpellToInterrupt") return end -- storm bolt
				if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
				if GS.PlayerHasTalent(2, 3) and GS.SCA(103840) and GS.SpellCDDuration(23922, nil) <= 1.5 then GS.Cast("target", 103840, nil) return end -- impending victory
				if not GS.PlayerHasTalent(2, 3) and GS.SCA(34428, "target", interruptCasting) and GS.SpellCDDuration(23922, nil) <= 1.5 then GS.Cast("target", 34428, false, false, false, "SpellToInterrupt") return end -- victory rush
				if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute with buff
				if GS.SCA(20243, "target", interruptCasting) then GS.Cast("target", 20243, false, false, false, "SpellToInterrupt") return end -- devastate
				if GS.SCA(57755, "target", interruptCasting) then GS.Cast("target", 57755, false, false, false, "SpellToInterrupt") return end -- heroic throw
			end
		end
	end

	function GS.WARRIORGLAD() -- level 100 talent
		if GetShapeshiftForm() ~= 1 then CastShapeshiftForm(1) return end
		if GS.Combat() then
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			GS.MultiDoT("Deep Wounds")
			if GS.ValidTarget() then
				StartAttack("target")
				if GS.CDs then
					if GS.PlayerHasTalent(6, 2) and GS.SIR(12292) then GS.Cast("target", 12292, false, false, false, "SpellToInterrupt") end -- blood bath
					if GS.PlayerHasTalent(6, 1) and GS.SIR(107574) then GS.Cast("target", 107574, false, false, false, "SpellToInterrupt") end -- avatar

					if (GS.Aura("player", 12292) or GS.Aura("player", 107574) or GS.Aura("player", 169667) or (GetNumArenaOpponents() == 0 and GS.TTD[ObjectPointer("target")] < 10)) then
						if GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 then UseInventoryItem(13) return end -- trinket 1
						-- if GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 then UseInventoryItem(14) return end -- trinket 2
						if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast("player", 20572, nil) return end -- blood fury
						if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end -- berserking
						if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(69197) and GS.PP(true)-GS.PP() > 40 then GS.Cast("player", 69197, nil) return end -- arcane torrent
						-- actions+=/potion,name=draenic_armor
					end
				end

				if GS.SCA(156321, "target", interruptCasting) and (GetSpellCharges(156321) == 2 or (not GS.Aura("player", 169667) and GS.SpellCDDuration(23922, nil) == 0)) then GS.Cast("target", 156321, false, false, false, "SpellToInterrupt") return end -- shield charge
				if GS.SIR(18499) and not GS.Aura("player", 12880) then GS.Cast("target", 18499, false, false, false, "SpellToInterrupt") end -- berserker rage enrage not up

				local unyieldingStrikesStacks = select(4, GS.Aura("player", 169686)) or 0
				if GS.SCA(78, "target", interruptCasting) and (GS.Aura("player", 169667) or (GS.Aura("player", 169686) and GS.PP() >= (50-unyieldingStrikesStacks*5))) and GS.Health("target", maxhealth, true) > 20 then GS.Cast("target", 78, false, false, false, "SpellToInterrupt") return end -- heroic strike
				if GS.SCA(78, "target", interruptCasting) and (GS.Aura("player", 122510) or (GS.PP() >= (GS.PP(true)-20)) or unyieldingStrikesStacks > 4 or (GetNumArenaOpponents() == 0 and GS.TTD[ObjectPointer("target")] < 10)) then GS.Cast("target", 78, false, false, false, "SpellToInterrupt") return end -- heroic strike

				if GS.PlayerCount(8) > 1 then
					if GS.SCA(6572, "target", interruptCasting) then GS.Cast("target", 6572, false, false, false, "SpellToInterrupt") return end -- revenge
					if GS.SCA(23922, "target", interruptCasting) then GS.Cast("target", 23922, false, false, false, "SpellToInterrupt") return end -- shield slam
					if not GS.PlayerHasTalent(6, 2) or (GS.Aura("player", 12292) or ((GS.PlayerHasTalent(4, 3) and GS.SpellCDDuration(12292, nil) > 10)) or (GS.PlayerHasTalent(4, 1) and GS.SpellCDDuration(12292, nil) > 7)) then
						if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end
						if GS.PlayerHasTalent(4, 1) and GS.SCA(107570, "target", interruptCasting) then GS.Cast("target", 107570, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SIR(6343) and GS.PlayerCount(8) > 4 then
						for i = 1, #tNoObjectDeepWounds do
							if GS.Distance(tNoObjectDeepWounds[i], nil) <= 8 then
								GS.Cast("target", 6343, false, false, false, "SpellToInterrupt")
								return
							end
						end
						for i = 1, #tDeepWounds do
							if GS.Distance(tDeepWounds[i], nil) <= 8 and GS.AuraRemaining(tDeepWounds[i], 115767, 3, "", "PLAYER") then
								GS.Cast("target", 6343, false, false, false, "SpellToInterrupt")
								return
							end
						end
					end
					if GS.PlayerHasTalent(6, 3) and not GS.Aura("player", 169667) and GS.SIR(46924) then GS.Cast("target", 46924, false, false, false, "SpellToInterrupt") return end -- bladestorm
					if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute with buff
					if GS.SIR(6343) and GS.PlayerCount(8) > 6 then GS.Cast("target", 6343, false, false, false, "SpellToInterrupt") return end -- thunder clap

					if GS.SIR(20243) and GS.SpellCDDuration(23922, nil) > 0.6 then
						for i = 1, #tNoObjectDeepWounds do if GS.SCA(20243, tNoObjectDeepWounds[i], interruptCasting) then GS.Cast(tNoObjectDeepWounds[i], 20243, false, false, false, "SpellToInterrupt") return end end -- devastate cycle deep wounds
						for i = 1, #tDeepWounds do if GS.SCA(20243, tDeepWounds[i], interruptCasting) and GS.AuraRemaining(tDeepWounds[i], 115767, 5, "", "PLAYER") then GS.Cast(tDeepWounds[i], 20243, false, false, false, "SpellToInterrupt") return end end -- devastate cycle deep wounds
						if GS.SCA(20243, "target", interruptCasting) then GS.Cast("target", 20243, false, false, false, "SpellToInterrupt") return end -- devastate if shield slam not coming up soon
					end
				end

				if GS.SCA(20243, "target", interruptCasting) and GS.Aura("player", 169686) and not GS.AuraStacks("player", 169686, 6) and GS.AuraRemaining("player", 169686, 1.5) then GS.Cast("target", 20243, false, false, false, "SpellToInterrupt") return end -- devastate refresh unyielding strikes
				if GS.SCA(23922, "target", interruptCasting) then GS.Cast("target", 23922, false, false, false, "SpellToInterrupt") return end -- shield slam
				if GS.SCA(6572, "target", interruptCasting) then GS.Cast("target", 6572, false, false, false, "SpellToInterrupt") return end -- revenge
				if GS.SCA(5308, "target", interruptCasting) and GS.Aura("player", 52437) then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute with buff
				if GS.PlayerHasTalent(4, 1) and GS.SCA(107570, "target", interruptCasting) then GS.Cast("target", 107570, false, false, false, "SpellToInterrupt") return end -- storm bolt
				if GS.PlayerHasTalent(4, 3) and GS.SIR(118000) and GS.Distance("target", nil) <= 8+UnitCombatReach("target") then GS.Cast("target", 118000, false, false, false, "SpellToInterrupt") return end -- dragon roar
				if GS.SCA(5308, "target", interruptCasting) and GS.PP() > 60 and GS.Health("target", false, true) < 20 then GS.Cast("target", 5308, false, false, false, "SpellToInterrupt") return end -- execute rage dump execute range
				if GS.SCA(20243, "target", interruptCasting) then GS.Cast("target", 20243, false, false, false, "SpellToInterrupt") return end -- devastate
			end
		end
	end

	function GS.PALADIN1() -- holy
		if GS.Combat() and not GS.IsCAOCH() then

			if GS.PlayerHasTalent(6, 1) and GS.SCA(114165, "target") and GS.ValidTarget() then GS.Cast("target", 114165, false, false, false, "SpellToInterrupt") return end

			if GS.SIR(20473) and GS.PP() < 3 then -- holy shock
				local healing = GS.PaladinHealing("Holy Shock")

				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(20473, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 20473, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(20473, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 20473, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(20473, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 20473, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
						if GS.SCA(20473, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 20473, false, false, false, "SpellToInterrupt") return end
					end
				end
			end

			if GS.PP() >= 3 then
				if GS.PlayerHasTalent(3, 3) then -- sacred shield finishing
					if GS.SIR(85222) then GS.Cast("player", 85222, false, false, false, "SpellToInterrupt") return end
				elseif GS.PlayerHasTalent(3, 2) then -- eternal flame finishing
					if GS.SIR(114163) then
						for k,v in ipairs(GS.Players[tanksIndex].Players) do
							if not (GS.Aura(v.Player, 156322) and GS.Players[tanksIndex].Players[k+1] and not GS.Aura(GS.Players[tanksIndex].Players[k+1], 156322)) then
								GS.Cast(v.Player, 114163, false, false, false, "SpellToInterrupt")
								return
							end
						end
					end
				else -- selfless healer finishing
				end
			end

			if IsShiftKeyDown() then
				if GS.SCA(82327, "player", interruptCasting) then GS.Cast("player", 82327, false, false, false, "SpellToInterrupt") return end
			elseif IsAltKeyDown() then
				local healing = GS.PaladinHealing("Holy Light")

				if GS.Aura("player", 54149) then
					for k,v in ipairs(GS.Players[tanksIndex].Players) do
						if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players[dpsIndex].Players) do
						if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players[healersIndex].Players) do
						if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players) do
						if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
							if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt") return end
						end
					end
				else
					for k,v in ipairs(GS.Players[tanksIndex].Players) do
						if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(19750, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 19750, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players[dpsIndex].Players) do
						if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(19750, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 19750, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players[healersIndex].Players) do
						if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
							break
						end
						if GS.SCA(19750, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 19750, false, false, false, "SpellToInterrupt") return end
					end

					for k,v in ipairs(GS.Players) do
						if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
							if GS.SCA(19750, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 19750, false, false, false, "SpellToInterrupt") return end
						end
					end
				end
			else
				local healing = GS.PaladinHealing("Holy Light")

				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then

						GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt")
						return
					end
				end

				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then
						GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt")
						return
					end
				end

				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then
						GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt")
						return
					end
				end

				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
						if GS.SCA(82326, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 82326, false, false, false, "SpellToInterrupt") return end
					end
				end
			end
		end
	end

	function GS.PALADIN2() -- protection
		if (not GSR.ProtectionPaladinMode or GSR.ProtectionPaladinMode == 1 or GSR.ProtectionPaladinMode == 3) and not GS.Combat() and GetShapeshiftForm() ~= 3 then CastShapeshiftForm(3) return end -- seal of insight
		if GSR.ProtectionPaladinMode == 2 and not GS.Combat() and GetShapeshiftForm() ~= 2 then CastShapeshiftForm(2) return end -- seal of righteousness
		GS.PaladinBuffs()
		-- actions.precombat+=/sacred_shield dbm timer maybe?
		if GS.Combat() then
			if GS.PlayerHasTalent(7, 1) then
				GS.Paladin.Seals.curSeal = GetShapeshiftForm()
				if GS.Aura("player", 156988) then
					_, _, _, _, _, _, GS.Paladin.Seals.uthersExpires = GS.Aura("player", 156988)
					GS.Paladin.Seals.uthersRemaining = GS.Paladin.Seals.uthersExpires-GetTime()
				else
					GS.Paladin.Seals.uthersRemaining = 0
				end
				if GS.Aura("player", 156989) then
					_, _, _, _, _, _, GS.Paladin.Seals.liadrinsExpires = GS.Aura("player", 156989)
					GS.Paladin.Seals.liadrinsRemaining = GS.Paladin.Seals.liadrinsExpires-GetTime()
				else
					GS.Paladin.Seals.liadrinsRemaining = 0
				end
				if GS.Aura("player", 156990) then
					_, _, _, _, _, _, GS.Paladin.Seals.maraadsExpires = GS.Aura("player", 156990)
					GS.Paladin.Seals.maraadsRemaining = GS.Paladin.Seals.maraadsExpires-GetTime()
				else
					GS.Paladin.Seals.maraadsRemaining = 0
				end
			end
			if GS.ValidTarget() then
				StartAttack("target")
				if GSR.Taunt then GS.Taunt() end
				if GSR.Interrupt then GS.Interrupt() end

				if GS.Paladin.Stun == 1 and GS.SCA(853) then -- hammer of justice
					GS.Cast(nil, 853)
					return
				end

				if GS.Paladin.BlindingLight == 1 and GS.SIR(115750) then
					GS.Cast(nil, 115750)
					return
				end
				if GS.Paladin.DivineShield == 1 and GS.SIR(642) then
					GS.Cast(nil, 642)
					return
				end

				-- actions.max_dps+=/potion,name=draenic_armor,if=buff.holy_avenger.react|buff.bloodlust.react|target.time_to_die<=60

				if GS.PlayerHasTalent(7, 2) and GS.SIR(152262) and (GSR.ProtectionPaladinMode ~= 3) then GS.Cast("target", 152262, false, false, false, "SpellToInterrupt") return end -- seraphim mixed and max dps

				if GSR.DivineProtection and GS.SIR(498) and (not GS.PlayerHasTalent(7, 2) or (GS.SpellCDDuration(152262, nil) > 5 and GS.SpellCDDuration(152262, nil) < 9)) then GS.Cast(nil, 498) end -- divine protection

				if GS.PlayerHasTalent(7, 2) and GS.SIR(152262) and GSR.ProtectionPaladinMode == 3 and not GS.Aura("player", 498) and GS.SpellCDDuration(498, nil) > 0 then GS.Cast("target", 152262, false, false, false, "SpellToInterrupt") return end -- seraphim max survival

				if GS.Aura("player", 90174) and GS.SCA(53600) then GS.Cast(nil, 53600) end -- divine purpose sotr dump all modes
				if GS.SCA(53600, "target", interruptCasting) and (GS.PP() == 5 or (GSR.ProtectionPaladinMode == 2 and GS.PlayerHasTalent(5, 1)) --[[or incoming_damage_1500ms>=health.max*0.3 for mixed and survival]]) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > 5) then GS.Cast("target", 53600, false, false, false, "SpellToInterrupt") return end -- sotr at 5 HP or holy avenger talent in max dps is on AND seraphim check
				if GS.SCA(53600, "target", interruptCasting) and GS.Aura("player", 105809) and not GS.AuraRemaining("player", 105809, GS.TTHPG()) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > GS.TTHPG()) then GS.Cast("target", 53600, false, false, false, "SpellToInterrupt") return end -- sotr holy avenger dump


				if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast(nil, 20572)  return end -- Blood Fury
				if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast(nil, 26297)  return end -- Berserking
				if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(155145) and GS.PP() < 5 then GS.Cast(nil, 155145)  return end -- Arcane Torrent
				-- actions.max_dps=potion,name=draenic_armor,if=buff.holy_avenger.react|buff.bloodlust.react|target.time_to_die<=60

				if GS.PlayerHasTalent(7, 1) and (GSR.ProtectionPaladinMode == 1 or not GSR.ProtectionPaladinMode) and GS.SpellCDDuration(61304, nil) == 0 then -- keep updated: remove seal of truth upcoming patch
					if GS.Paladin.Seals.curSeal ~= 3 and GS.AuraRemaining("player", 156988, GS.SpellCDDuration(20271)) then CastShapeshiftForm(3) return end
					if GS.Paladin.Seals.curSeal ~= 2 and not GS.AuraRemaining("player", 156988, GS.SpellCDDuration(20271)) and not GS.Aura("player", 156989) then CastShapeshiftForm(2) return end
					if GS.Paladin.Seals.curSeal ~= 1 and not GS.AuraRemaining("player", 156988, GS.SpellCDDuration(20271)) and not GS.AuraRemaining("player", 156989, GS.SpellCDDuration(20271)) and not GS.Aura("player", 156990) then CastShapeshiftForm(1) return end
				end

				if GSR.ProtectionPaladinMode ~= 3 and GS.AoE and GS.SCA(31935) and not GS.PlayerHasGlyph(54930) and GS.Aura("player", 85416) and GS.TargetCount(10) > 1 then -- Avenger's Shield AoE Buff
					GS.Cast(nil, 31935)
					return
				end

				if GSR.ProtectionPaladinMode == 2 and GS.PlayerHasTalent(5, 2) and GS.SIR(119072) and GS.PlayerCount(10) > 0 and (GS.Aura("player", 152262) or (GS.PlayerHasGlyph(54935) and GS.Health("target", false, true) <= 20)) then
					GS.Cast(nil, 119072)
					return
				end -- holy wrath

				if GS.AoE and GS.SCA(35395) and GS.TargetCount(8) >= 3 then -- Hammer of the Righteous
					GS.Cast(nil, 53595)
					return
				end

				if GSR.ProtectionPaladinMode == 2 and GS.PlayerHasTalent(7, 1) and GS.SCA(20271) and (not GS.Aura("player", 156990) or not GS.Aura("player", 156989)) then -- keep udpated: remove seal of truth upcoming patch @protectionPaladin
					GS.Cast(nil, 20271)
					return
				end

				if GS.SCA(35395) then -- Crusader Strike
					GS.Cast(nil, 35395)
					return
				end
				if GS.SpellCDDuration(35395) > 0 and GS.SpellCDDuration(35395) <= 0.35 then return end -- crusader strike wait

				if GS.SIR(20271) and GS.PlayerHasGlyph(54922) then
					if GS.SCA(20271, "target", interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID("target") ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
						GS.Cast("target", 20271, false, false, false, "SpellToInterrupt")
						GS.Paladin.DoubleJeopardy = ObjectPointer("target")
						return
					elseif GS.AoE then
						for i = 1, #GS.Targets do
							if GS.SCA(20271, GS.Targets[i], interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID(GS.Targets[i]) ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
								GS.Cast(GS.Targets[i], 20271, false, false, false, "SpellToInterrupt")
								GS.Paladin.DoubleJeopardy = GS.Targets[i]
								return
							end
						end
					end
				end

				if GS.SCA(20271) then -- judgment
					GS.Cast(nil, 20271)
					return
				end
				if GS.SpellCDDuration(20271) > 0 and GS.SpellCDDuration(20271) <= 0.35 then return end -- judgment wait

				if GS.SCA(31935) and GS.AoE and GS.TargetCount(10) > 1 and (not GS.PlayerHasGlyph(54930) or GSR.ProtectionPaladinMode == 3) and (GSR.ProtectionPaladinMode ~= 3 or GS.Aura("player", 85416)) then -- Avenger's Shield Cleave
					GS.Cast(nil, 31935)
					return
				end

				if GS.PlayerHasTalent(5, 2) and GS.SIR(119072) and GS.PlayerCount(10) > 0 then
					GS.Cast(nil, 119072)
					return
				end -- Holy Wrath Talent

				if GS.SCA(31935) and GS.Aura("player", 85416) then -- Avenger's Shield Grand Crusader
					GS.Cast(nil, 31935)
					return
				end

				if GSR.ProtectionPaladinMode ~= 2 and GS.PlayerHasTalent(3, 3) and GS.AuraRemaining("player", 20925, 2, "", "PLAYER") and GS.SIR(20925) then GS.Cast("player", 20925) return end -- sacred shield

				if GSR.ProtectionPaladinMode == 2 and GS.PlayerHasTalent(6, 3) and GS.SIR(114157) and GS.TargetCount(10) < 3 then GS.Cast(nil, 114157) return end -- execution sentence

				if GSR.ProtectionPaladinMode ~= 3 and GS.PlayerHasGlyph(54935) and GS.Health("target", false, true) <= 20 and GS.SIR(119072) and GS.Distance("target") <= 10+GS.CombatReach("target") then GS.Cast(nil, 119072) return end -- final wrath

				if GS.SCA(31935) then GS.Cast(nil, 31935) return end -- Avenger's Shield

				if GS.PlayerHasTalent(7, 1) and GSR.ProtectionPaladinMode == 2 and GS.SpellCDDuration(61304, nil) == 0 then -- keep updated: remove seal of truth upcoming patch @protectionPaladin
					if GS.Paladin.Seals.curSeal ~= 1 and GS.AuraRemaining("player", 156990, GS.SpellCDDuration(20271)) then CastShapeshiftForm(1) return end
					if GS.Paladin.Seals.curSeal ~= 2 and not GS.AuraRemaining("player", 156990, GS.SpellCDDuration(20271)) and not GS.Aura("player", 156989) then CastShapeshiftForm(2) return end
					-- actions.max_dps+=/seal_of_righteousness,if=talent.empowered_seals.enabled&!seal.righteousness
				end

				if GS.PlayerHasTalent(6, 2) and GS.SIR(114158) and GS.PlayerCount(10) > 0 and ((GSR.ProtectionPaladinMode == 2 or GSR.ProtectionPaladinMode == 3) or (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) < 6 or not GS.AuraRemaining("player", 152262, 10))) then GS.Cast("player", 114158) return end -- light's hammer dropped on you based on # around you
				if GS.PlayerHasTalent(6, 1) and GS.SIR(114165) and ((GSR.ProtectionPaladinMode == 2 or GSR.ProtectionPaladinMode == 3) or (not GS.PlayerHasTalent(7, 2) or GS.Aura("player", 152262) or GS.SpellCDDuration(152262, nil) > 5 or (GetTime()-GS.CombatStart) < 5)) then
					if GS.AoE and GS.PlayerCount(15) > 1 then GS.Cast("player", 114165) return end -- holy prism aoe
					GS.Cast("target", 114165) -- holy prism single target
					return
				end

				if GS.SIR(26573) and not GS.PlayerHasGlyph(54928) and GS.PlayerCount(8) >= 3 then GS.Cast(nil, 26573) return end -- consecration non glyphed
				if GS.SIR(26573) and GS.PlayerHasGlyph(54928) then GS.Cast("target", 26573, GS.SmartAoE(25, 8, true)) return end -- consecration at your target glyphed

				if GS.PlayerHasTalent(6, 3) and GS.SCA(114157) and not GS.Aura("target", 145065) and not GS.Aura("target", 145171) and ((GSR.ProtectionPaladinMode == 2 or GSR.ProtectionPaladinMode == 3) or (not GS.PlayerHasTalent(7, 2) or GS.Aura("player", 152262) or (GetTime()-GS.CombatStart) < 12)) then GS.Cast(nil, 114157) return end -- execution sentence not touch of y'shaarg + empowered
				if GSR.ProtectionPaladinMode == 3 then if GS.PlayerHasTalent(3, 1) and GS.AuraStacks("player", 114250, 3) and GS.SIR(19750) then GS.Cast("player", 19750) return end end -- flashoflight

				if GS.SCA(24275) then GS.Cast(nil, 24275) return end -- hammer of wrath

				if GSR.ProtectionPaladinMode ~= 2 and GS.PlayerHasTalent(3, 3) and GS.AuraRemaining("player", 20925, 8) and GS.SIR(20925) then GS.Cast("player", 20925) return end -- Sacred Shield refresh 8

				if GSR.ProtectionPaladinMode == 3 then if GS.PlayerHasGlyph(54935) and GS.Health("target", false, true) <= 20 and GS.SIR(119072) and GS.Distance("target") <= 10+GS.CombatReach("target") then GS.Cast(nil, 119072) return end end -- Final Wrath

				if GS.SIR(26573) and not GS.PlayerHasGlyph(54928) and GS.PlayerCount(8) > 0 then GS.Cast("player", 26573, false, false, false, "SpellToInterrupt") return end -- consecration
				
				if GS.SIR(119072) and GS.PlayerCount(10) > 0 then GS.Cast(nil, 119072) return end -- Holy Wrath

				if GS.PlayerHasTalent(7, 1) and (GSR.ProtectionPaladinMode == 1 or not GSR.ProtectionPaladinMode) and GS.SpellCDDuration(61304) == 0 then -- keep updated: take out seal of truth upcoming patch
					if GS.Paladin.Seals.curSeal ~= 3 and GS.Aura("player", 156989) and GS.Aura("player", 156990) and GS.AuraRemaining("player", 156988, GS.Paladin.Seals.liadrinsRemaining) and GS.AuraRemaining("player", 156988, GS.Paladin.Seals.maraadsRemaining) then CastShapeshiftForm(3) return end
					if GS.Paladin.Seals.curSeal ~= 2 and GS.Aura("player", 156988) and GS.Aura("player", 156990) and GS.AuraRemaining("player", 156989, GS.Paladin.Seals.uthersRemaining) and GS.AuraRemaining("player", 156989, GS.Paladin.Seals.maraadsRemaining) then CastShapeshiftForm(2) return end
					if GS.Paladin.Seals.curSeal ~= 1 and GS.Aura("player", 156988) and GS.Aura("player", 156989) and GS.AuraRemaining("player", 156990, GS.Paladin.Seals.uthersRemaining) and GS.AuraRemaining("player", 156990, GS.Paladin.Seals.liadrinsRemaining) then CastShapeshiftForm(1) return end
				end

				if GS.PlayerHasTalent(7, 1) and GSR.ProtectionPaladinMode == 2 and GS.SpellCDDuration(61304) == 0 then -- keep updated: remove this [[seal of truth]] upcoming patch @protectionPaladin
					if GS.Paladin.Seals.curSeal ~= 1 and GS.AuraRemaining("player", 156990, GS.Paladin.Seals.liadrinsRemaining) then CastShapeshiftForm(1) return end
					if GS.Paladin.Seals.curSeal ~= 2 and GS.Aura("player", 156990) and GS.AuraRemaining("player", 156989, GS.Paladin.Seals.maraadsRemaining) then CastShapeshiftForm(2) return end
				end

				if GSR.ProtectionPaladinMode ~= 3 and GS.PlayerHasTalent(3, 1) and GS.AuraStacks("player", 114250, 3) and GS.SIR(19750) then GS.Cast("player", 19750) return end -- flashoflight

				if GS.PlayerHasTalent(3,3) and GS.SIR(20925) then GS.Cast("player", 20925) return end -- Sacred Shield
			end
		end
	end

	function GS.PALADIN3() -- retribution
		GS.PaladinBuffs()
		-- actions.precombat+=/seal_of_truth,if=active_enemies<2
		-- actions.precombat+=/seal_of_righteousness,if=active_enemies>=2
		if GS.Combat() then

			if GS.ValidTarget() and GS.Paladin.Stun == 1 and GS.SCA(853) then -- stun
				GS.Cast(nil, 853)
				return
			end

			if GS.Paladin.BlindingLight == 1 and GS.SIR(115750) then
				GS.Cast(nil, 115750)
				return
			end
			if GS.Paladin.DivineShield == 1 and GS.SIR(642) then
				GS.Cast(nil, 642)
				return
			end

			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
		end

		if GS.Combat() and GS.ValidTarget() then
			if GSR.Interrupt then GS.Interrupt() end
			
			StartAttack("target")

			if GS.SCA(20271, "target", interruptCasting) and GS.PlayerHasTalent(7, 1) and (GetTime()-GS.CombatStart) < 2 then GS.Cast("target", 20271, false, false, false, "SpellToInterrupt") return end -- judgment for buff

			if GS.PlayerHasTalent(6, 3) and GS.SCA(114157) and not GS.Aura("target", 145065) and not GS.Aura("target", 145171) then
				GS.Cast(nil, 114157)
				return
			end -- execution sentence

			if GS.PlayerHasTalent(6, 2) and GS.SIR(114158) and (GS.Distance("target") <= 10 or GS.PlayerCount(10) > 0) then
				GS.Cast(nil, 114158, GS.SmartAoE(30, 10, true))
				return
			end -- light's hammer

			-- cooldowns
			if GS.CDs and GS.PlayerHasTalent(5, 1) and GS.UnitIsBoss("target") and not GS.PlayerHasTalent(7,2) and GS.SIR(105809) and GS.PP() <= 2 and GS.SpellCDDuration(61304, nil) == 0 then -- holy avenger
				GS.Cast(nil, 105809)
				return
			end
			if GS.CDs and GS.UnitIsBoss("target") and not GS.PlayerHasTalent(7,2) and GS.SIR(31884) and GS.SpellCDDuration(61304, nil) == 0 then -- avenging wrath
				GS.Cast(nil, 31884)
				return
			end
			if GS.CDs and GS.Aura("player", 31884) and GS.UnitIsBoss("target") and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 then UseInventoryItem(13) return end -- trinket 1
			if GS.CDs and GS.Aura("player", 31884) and GS.UnitIsBoss("target") and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 then UseInventoryItem(14) return end -- trinket 2

			if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast(nil, 20572)  return end -- blood fury
			if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast(nil, 26297)  return end -- berserking
			if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(155145) and GS.PP() < 5 then GS.Cast(nil, 155145)  return end -- Arcane Torrent
			if GS.PlayerHasTalent(7,2) and GS.SIR(152262) then -- seraphim
				if GS.CDs and GS.UnitIsBoss("target") then
					if GS.SIR(31884) then GS.Cast(nil, 31884) end
					if GS.SIR(105809) then GS.Cast(nil, 105809) end
				end
				GS.Cast(nil, 152262)
				return
			end
			if GS.PlayerHasTalent(7, 2) and GS.PP() == 5 and GS.SpellCDDuration(152262, nil) > 0 and GS.SpellCDDuration(152262, nil) < (1.5/(1+GetHaste()*.001)) then return end -- wait for seraphim
			-- cooldowns

			if GS.AoE and GS.PlayerCount(8) >= 3 then
				if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and not GS.Aura("player", 157048) and GS.PP() == 5 then GS.Cast(nil, 157048) return end -- final verdict for buff
				if GS.SIR(53385) and GS.PP() == 5 then
					if GS.Aura("player", 157048) or (not GS.PlayerHasTalent(7, 3) and (GS.Aura("player", 144595) or (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*4))) then GS.Cast(nil, 53385) return end -- Divine Storm dump
				end
				if GS.SCA(24275) then GS.Cast(nil, 24275) return end -- hammer of wrath
				if GS.PlayerHasTalent(7,1) and GS.SCA(20271) and GetShapeshiftForm() == 2 and GS.AuraRemaining("player", 156989, GS.SpellCDDuration(20271, nil)) then GS.Cast(nil, 20271) return end -- Judgment Righteousness buff
				if GS.Aura("player", 166831) and GS.PP() <= 2 and not GS.Aura("player", 105809) then
					if not GS.PlayerHasGlyph(122028) and GS.SCA(879, "target") then
						GS.Cast("target", 879, nil)
						return
					elseif GS.PlayerHasGlyph(122028) and GS.SCA(122032, "target") then
						GS.Cast(nil, 122032)
						return
					end
				end -- exorcism 3 holy power
				if GS.SIR(53385) and GS.Aura("player", 157048) and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
				if GS.PlayerHasTalent(7, 3) and GS.SCA(157048, "target", interruptCasting) and not GS.Aura("player", 157048) and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast("target", 157048, false, false, false, "SpellToInterrupt") return end
				if GS.SIR(53385) and GS.Aura("player", 144595) and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
				if GS.SIR(53385) and GS.PP() == 5 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*3) and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
				if GS.SIR(53385) and GS.PP() == 4 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*4) and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
				if GS.SIR(53385) and GS.PP() == 3 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*5) and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
				if GS.SCA(53595) and GS.PlayerCount(8) >= 4 and (GS.PP() <= 3 or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and GS.Health("target", maxhealth, true) >= 35 and not GS.Aura("player", 31884))) then GS.Cast(nil, 53595) return end -- Hammer of the Righteous
				if GS.SCA(35395) and (GS.PP() <= 3 or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and not GS.Aura("player", 31884) and GS.Health("target", maxhealth, true) >= 35)) then GS.Cast(nil, 35395) return end -- crusader strike
				if GS.PlayerHasGlyph(122028) and GS.SCA(122032) and GS.PP() < 5 then GS.Cast(nil, 122032) return end -- mass exorcism
				if GS.SIR(20271) and GS.PlayerHasGlyph(54922) and GS.PP() < 5 then
					if GS.SCA(20271, "target", interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID("target") ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
						GS.Cast("target", 20271, false, false, false, "SpellToInterrupt")
						GS.Paladin.DoubleJeopardy = ObjectPointer("target")
						return
					elseif GS.AoE then
						for i = 1, #GS.Targets do
							if GS.SCA(20271, GS.Targets[i], interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID(GS.Targets[i]) ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
								GS.Cast(GS.Targets[i], 20271, false, false, false, "SpellToInterrupt")
								GS.Paladin.DoubleJeopardy = GS.Targets[i]
								return
							end
						end
					end
				end
				if GS.SCA(20271) and (GS.PP() <= 3 or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and not GS.Aura("player", 31884) and GS.Health("target", maxhealth, true) >= 35 and GS.SpellCDDuration(35395, nil) > (1.5/(1+GetHaste()*.01))*2)) then GS.Cast(nil, 20271) return end -- judgment
				if not GS.PlayerHasGlyph(122028) and (GS.PP() <= 3 or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and GS.SpellCDDuration(20271, nil) > (1.5/(1+GetHaste()*.01))*2 and GS.SpellCDDuration(35395, nil) > (1.5/(1+GetHaste()*.01))*2 and not GS.Aura("player", 31884) and GS.Health("target", maxhealth, true) >= 35)) and GS.SCA(879, "target") then
					GS.Cast("target", 879, nil)
					return
				end
				if GS.PP() >= 3 then
					if GS.SIR(53385) and (GS.Aura("player", 157048) or not GS.PlayerHasTalent(7, 3) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*6)) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
					if GS.PlayerHasTalent(7, 3) and GS.SCA(157048, "target", interruptCasting) and not GS.Aura("player", 157048) then GS.Cast("target", 157048, false, false, false, "SpellToInterrupt") return end
				end
				if GS.PlayerHasTalent(6, 1) and GS.SIR(114165) then GS.Cast("player", 114165) return end -- holy prism
			end

			if GS.SIR(53385) and GS.Aura("player", 144595) and (GS.PP() == 5 or GS.PP() >= 3 and GS.Aura("player", 105809)) and GS.Aura("player", 157048) and GS.PlayerCount(16) > 0 then GS.Cast(nil, 53385) return end -- divine storm final verdict dump
			if not GS.PlayerHasTalent(7, 3) and GS.SIR(53385) and GS.Aura("player", 144595) and (GS.PP() == 5 or GS.PP() >= 3 and GS.Aura("player", 105809)) and GS.PlayerCount(8) == 2 then GS.Cast(nil, 53385, nil) return end -- divine storm cleave
			if GS.PlayerHasTalent(7, 3) and GS.SIR(53385) and (GS.PP() == 5 or GS.PP() >= 3 and GS.Aura("player", 105809)) and GS.PlayerCount(8) == 2 and GS.Aura("player", 157048) then GS.Cast(nil, 53385, nil) return end -- divine storm cleave
			if GS.PlayerHasTalent(7, 2) and GS.SIR(53385) and GS.PlayerCount(8) > 0 and GS.Aura("player", 144595) and (GS.PP() == 5 or GS.PP() >= 3 and GS.Aura("player", 105809)) and GS.SpellCDDuration(152262) < (1.5/(1+GetHaste()*.01))*4 then GS.Cast(nil, 53385, nil) return end -- divine storm dump before seraphim

			if GS.SCA(85256) and (GS.PP() == 5 or (GS.Aura("player", 105809) and GS.PP() >= 3 and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262) > (1.5/(1+GetHaste()*.01))*4))) then GS.Cast(nil, 85256) return end -- TV
			if GS.SCA(85256) and GS.Aura("player", 90174) and GS.AuraRemaining("player", 90174, 3) then GS.Cast(nil, 85256) return end -- TV DV Dump
			if not GS.PlayerHasTalent(7, 3) and GS.SIR(53385) and GS.Aura("player", 144595) and GS.AuraRemaining("player", 144595, 3) and GS.PlayerCount(8) > 0 then GS.Cast(nil, 53385, nil) return end -- divine storm cleave
			if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and (GS.PP() == 5 or GS.Aura("player", 105809)) then GS.Cast(nil, 157048) return end -- FV
			if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and GS.Aura("player", 90174) and GS.AuraRemaining("player", 90174, 3) then GS.Cast(nil, 157048) return end -- FV DV Dump
			if GS.SCA(24275) then GS.Cast(nil, 24275) return end -- hammer of wrath
			if GS.PlayerHasTalent(7, 1) and GS.SCA(20271) and ((GetShapeshiftForm() == 1 and GS.AuraRemaining("player", 156990, (GetSpellBaseCooldown(20271)*.001/(1+GetHaste()*.01))*2)) or (GetShapeshiftForm() == 2 and GS.AuraRemaining("player", 156989, (GetSpellBaseCooldown(20271)*.001/(1+GetHaste()*.01))*2)) or (GetShapeShiftForm() == 2 and GS.SpellCDDuration(31884, nil) < GS.SpellCDDuration(20271, nil))) then GS.Cast(nil, 20271, nil) return end

			if GS.Aura("player", 166831) and GS.PP() <= 2 and not GS.Aura("player", 105809) then
				if not GS.PlayerHasGlyph(122028) and GS.SCA(879, "target") then
					GS.Cast("target", 879, nil)
					return
				elseif GS.PlayerHasGlyph(122028) and GS.SCA(122032, "target") then
					GS.Cast(nil, 122032)
					return
				end
			end -- exorcism 3 holy power

			if GS.PlayerHasTalent(7, 1) and GS.SpellCDDuration(61304, nil) == 0 then
				if GetShapeshiftForm() ~= 1 and not GS.Aura("player", 156990) then CastShapeshiftForm(1) return end
				if GetShapeshiftForm() ~= 1 and GS.SpellCDDuration(31884, nil) < GS.SpellCDDuration(20271, nil) and not GS.AuraRemaining("player", 156989, GS.SpellCDDuration(20271, nil)) then CastShapeshiftForm(1) return end
				if GetShapeshiftForm() ~= 2 and not GS.AuraRemaining("player", 156990, GS.SpellCDDuration(20271, nil)) and not GS.Bloodlust() and not GS.Aura("player", 31884) and not GS.Aura("player", 156989) then CastShapeshiftForm(2) return end
			end

			if GS.SIR(53385) and GS.Aura("player", 144595) and GS.Aura("player", 157048) and GS.PlayerCount(16) > 0 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast(nil, 53385) return end -- divine storm dc fv
			if GS.SIR(53385) and GS.Aura("player", 157048) and GS.PlayerCount(16) == 2 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end -- divine storm cleave fv + execute or av
			if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast(nil, 157048, nil) return end -- FV
			if GS.SIR(53385) and GS.Aura("player", 144595) and GS.PlayerCount(8) == 2 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end -- divine storm hp gen cleave
			if GS.SCA(85256, "target", interruptCasting) and GS.PP() == 5 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*3) then GS.Cast("target", 85256, false, false, false, "SpellToInterrupt") return end
			if GS.SCA(85256, "target", interruptCasting) and GS.PP() == 4 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*4) then GS.Cast("target", 85256, false, false, false, "SpellToInterrupt") return end
			if GS.SCA(85256, "target", interruptCasting) and GS.PP() == 3 and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262, nil) > (1.5/(1+GetHaste()*.01))*5) then GS.Cast("target", 85256, false, false, false, "SpellToInterrupt") return end
			if GS.SCA(35395) and GS.PP() < 5 and GS.PlayerHasTalent(7, 2) then GS.Cast(nil, 35395) return end -- Hammer of the Righteous
			if GS.SCA(35395) and (GS.PP() <= 3 or (GS.PP() == 4 and GS.Health("target", maxhealth, true) >= 35 and not GS.Aura("player", 31884))) then GS.Cast(nil, 35395) return end -- Hammer of the Righteous
			if not GS.PlayerHasTalent(7, 3) and GS.SIR(53385) and GS.PlayerCount(8) > 0 and GS.Aura("player", 144595) and (GS.Aura("player", 31884) or GS.Health("target", maxhealth, true) < 35) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
			if GS.PlayerHasTalent(7, 2) and GS.SIR(20271) and GS.PlayerHasGlyph(54922) and GS.PP() < 5 then -- judgment double jeopardy
				if GS.SCA(20271, "target", interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID("target") ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
					GS.Cast("target", 20271, false, false, false, "SpellToInterrupt")
					GS.Paladin.DoubleJeopardy = ObjectPointer("target")
					return
				elseif GS.AoE then
					for i = 1, #GS.Targets do
						if GS.SCA(20271, GS.Targets[i], interruptCasting) and (not GS.Paladin.DoubleJeopardy or UnitGUID(GS.Targets[i]) ~= UnitGUID(GS.Paladin.DoubleJeopardy)) then
							GS.Cast(GS.Targets[i], 20271, false, false, false, "SpellToInterrupt")
							GS.Paladin.DoubleJeopardy = GS.Targets[i]
							return
						end
					end
				end
			end
			if GS.PlayerHasGlyph(122028) and GS.SCA(122032, "target") and GS.PP() < 5 and GS.TargetCount(8) >= 2 and not GS.PlayerHasGlyph(54922) then -- mass exorcism
				GS.Cast(nil, 122032)
				return
			end
			if GS.SCA(20271) and GS.PP() < 5 and GS.PlayerHasTalent(7, 2) then GS.Cast(nil, 20271, nil) return end
			if GS.SCA(20271) and (GS.PP() <= 3 or (GS.PP() == 4 and GS.SpellCDDuration(35395, nil) >= (1.5/(1+GetHaste()*.01))*2 and GS.Health("target", maxhealth, true) > 35 and not GS.Aura("player", 31884))) then GS.Cast(nil, 20271, nil) return end
			if GS.SIR(53385) and GS.PlayerCount(8) > 0 and GS.Aura("player", 144595) and GS.Aura("player", 157048) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end
			if GS.SIR(53385) and GS.PlayerCount(16) == 2 and GS.PP() >= 4 and GS.Aura("player", 157048) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end -- divine storm dump cleave fv pp
			if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and GS.Aura("player", 90174) then GS.Cast(nil, 157048, nil) return end
			if GS.PlayerHasTalent(7, 3) and GS.SCA(157048) and GS.PP() >= 4 then GS.Cast(nil, 157048, nil) return end
			if GS.SIR(53385) and GS.Aura("player", 144595) and GS.PlayerCount(8) == 2 and GS.PP() >= 4 and not GS.PlayerHasTalent(7, 3) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end -- divine storm dump dc proc cleave pp not fv
			if GS.SCA(85256) and GS.Aura("player", 90174) then GS.Cast(nil, 85256) return end -- TV dump
			if GS.SIR(53385) and GS.Aura("player", 144595) and not GS.PlayerHasTalent(7, 3) and GS.PlayerCount(8) > 0 then GS.Cast(nil, 53385) return end -- divine storm dump
			if GS.SCA(85256) and GS.PP() >= 4 and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262) > (1.5/(1+GetHaste()*.01))*5) then GS.Cast(nil, 85256) return end -- TV dump
			if GS.PlayerHasTalent(7, 1) and GS.SpellCDDuration(61304) == 0 then
				if GetShapeshiftForm() ~= 1 and GS.AuraRemaining("player", 156990, GetSpellBaseCooldown(20271)*.001/(1+GetHaste()*.01)) then CastShapeshiftForm(1) return end
				if GetShapeshiftForm() ~= 2 and not GS.Bloodlust() and GS.AuraRemaining("player", 156989, GetSpellBaseCooldown(20271)*.001/(1+GetHaste()*.01)) then CastShapeshiftForm(2) return end
			end
			if not GS.PlayerHasGlyph(122028) and GS.SCA(879, "target") and ((GS.PP() <= 3) or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and (GS.SpellCDDuration(20271, nil) >= (1.5/(1+GetHaste()*.01))*2 and GS.SpellCDDuration(35395, nil) >= (1.5/(1+GetHaste()*.01))*2 and GS.Health("target", maxhealth, true) > 35 and not GS.Aura("player", 31884)))) then
				GS.Cast("target", 879, nil)
				return
			elseif GS.PlayerHasGlyph(122028) and GS.SCA(122032, "target") and ((GS.PP() <= 3) or (GS.PP() < 5 and GS.PlayerHasTalent(7, 2)) or (GS.PP() == 4 and (GS.SpellCDDuration(20271, nil) >= (1.5/(1+GetHaste()*.01))*2 and GS.SpellCDDuration(35395, nil) >= (1.5/(1+GetHaste()*.01))*2 and GS.Health("target", maxhealth, true) > 35 and not GS.Aura("player", 31884)))) then
				GS.Cast(nil, 122032)
				return
			end
			if GS.SIR(53385) and GS.PlayerCount(16) == 2 and GS.PP() >= 3 and GS.Aura("player", 157048) then GS.Cast("target", 53385, false, false, false, "SpellToInterrupt") return end -- divine storm dump pp fv
			if GS.PlayerHasTalent(7, 3) and GS.PP() >= 3 and GS.SCA(157048, "target", interruptCasting) then GS.Cast("target", 157048, false, false, false, "SpellToInterrupt") return end -- final verdict
			if GS.SCA(85256) and GS.PP() >= 3 and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152262) > (1.5/(1+GetHaste()*.01))*6) then GS.Cast(nil, 85256) return end -- TV dump
			if GS.PlayerHasTalent(6, 1) and GS.AoE and GS.SIR(114165) and GS.PlayerCount(15) > 1 then -- Holy Prism
				GS.Cast(nil, 114165, "player")
				return
			end
			if GS.PlayerHasTalent(6, 1) and GS.SIR(114165) then GS.Cast(nil, 114165) return end -- Holy Prism
		end -- retribution
	end

	function GS.HUNTER1() -- beast mastery  todo: barrage aoe cone check @hunter add pot
		if GS.Combat() then
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			local focusregen = GetPowerRegen()
			local focustimetomax = (120-GS.PP())/focusregen

			if GS.ValidTarget() then
				StartAttack("target")
				if GSR.Interrupt then GS.Interrupt() end
				if GS.CDs and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 then UseInventoryItem(13) end
				if GS.CDs and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 then UseInventoryItem(14) end
				if GS.CDs and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GSR.Race == "BloodElf" and GS.SIR(80483) then GS.Cast("player", 80483, nil) end -- arcane torrent
				if GS.CDs and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast("player", 20572, nil) end -- blood fury
				if GS.CDs and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) end -- berserking
				-- actions+=/potion,name=draenic_agility,if=buff.bestial_wrath.up

				if GS.PlayerHasTalent(4, 2) and GS.SIR(120679) then GS.Cast("target", 120679, nil) return end -- dire beast
				if GS.CDs and GS.SIR(19574) and GS.PP() > 60 and not GS.Aura("player", 19574) then GS.Cast("player", 19574, nil) return end -- bestial wrath
				if GS.AoE and GS.SCA(2643) and (GS.TargetCount(8) > 5 or (GS.TargetCount(8) > 1 and not GS.Aura("pet", 118455))) then GS.Cast("target", 2643, nil) return end -- multishot beast cleave
				if GS.CDs and GS.PlayerHasTalent(5, 3) and (GS.UnitIsBoss("target") or GetNumArenaOpponents() > 0) and GS.SIR(121818) and (GS.Aura("player", 133630) or GS.TTD[ObjectPointer("target")] <= 20) then GS.Cast("target", 121818, false, false, false, "SpellToInterrupt") return end -- STAMPEDE!!!!!!!!
				-- actions+=/barrage,if=active_enemies>1
				if GS.PlayerHasTalent(5, 1) and GS.SCA(131894) then GS.Cast("target", 131894, nil) return end -- amoc
				if GS.SCA(53351) and focustimetomax > 1 then GS.Cast("target", 53351, nil) return end -- kill shot
				if GS.SCA(34026) and GS.Distance("target", "pet") <= 25+GS.CombatReach("target") then GS.Cast("target", 34026, nil) return end -- kill command
				if GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target") and GS.Hunter.FocusingShotThrottle == 0 and GS.PP() < 50 then GS.Cast("target", 152245, nil) return end -- focusing shot
				if not GS.PlayerHasTalent(7, 2) and GS.SCA(77767, "target", interruptCasting) and GS.Hunter.PreSteadyFocus == 1 and GS.PP()+41 < 120 then GS.Cast("target", 77767, false, false, false, "SpellToInterrupt") return end -- steady focus
				if GS.PlayerHasTalent(6, 1) and GS.SCA(117050) then GS.Cast("target", 117050, nil) return end -- glaive toss
				if GS.PlayerHasTalent(6, 3) and GS.SIR(120360) and GS.Distance("target", nil) and GS.IsFacing("player", "target") then GS.Cast("target", 120360, nil) return end
				if GS.PlayerHasTalent(6, 2) and GS.SCA(109259, "target") and focustimetomax > (select(4, GetSpellInfo(109259))*0.001) then GS.Cast("target", 109259, nil) return end -- powershot
				if GS.AoE and not GS.PlayerHasTalent(7, 2) and GS.TargetCount(8) > 5 and GS.SCA(77767) then GS.Cast("target", 77767, nil) return end -- cobra shot aoe
				if GS.SCA(3044) and (GS.Aura("player", 19574) or GS.Aura("player", 34720)) then GS.Cast("target", 3044, nil) return end -- arcane shot dump cd
				if GS.SIR(82692) and not GS.IsCAOCH() and GS.AuraStacks("player", 19615, 5) then GS.Cast("player", 82692, nil) return end -- focus fire
				if GS.SCA(3044) and GS.PP() >= 64 then GS.Cast("target", 3044, nil) return end -- arcane shot
				if not GS.PlayerHasTalent(7, 2) and GS.SCA(77767) then GS.Cast("target", 77767, nil) return end -- cobra shot
			end
		end
	end

	function GS.HUNTER2() -- marksman todo: aoe cone check @framework turn on cooldowns, trinket, explosive trap @hunter
		if GS.Combat() and GS.ValidTarget() then
			StartAttack("target")
			local focusregen = GetPowerRegen()
			if GSR.Interrupt then GS.Interrupt() end
			-- actions+=/use_item,name=beating_heart_of_the_mountain
			-- actions+=/arcane_torrent,if=focus.deficit>=30
			-- actions+=/blood_fury
			-- actions+=/berserking
			-- actions+=/potion,name=draenic_agility,if=((buff.rapid_fire.up|buff.bloodlust.up)&(cooldown.stampede.remains<1))|target.time_to_die<=25

			if GS.SCA(53209) then GS.Cast(nil, 53209, nil) return end -- chimaera shot
			if GS.SCA(157708) then GS.Cast("target", 157708, nil) return end -- kill shot
			if GS.CDs and GS.SIR(3045) and GS.UnitIsBoss("target") then GS.Cast(nil, 3045, nil) return end -- rapid fire why have this here if we're supposed to pool?
			if GS.PlayerHasTalent(5, 3) and GS.SIR(121818) and (GS.Aura("player", 3045) or GS.Bloodlust() or GS.TTD[ObjectPointer ("target")] <= 20) then GS.Cast(nil, 121818, nil) return end -- stampede

			if GS.Aura("player", 3045) or GS.Health("target", false, true) >= 80 then
				-- actions.careful_aim=glaive_toss,if=active_enemies>2
				-- actions.careful_aim+=/powershot,if=active_enemies>1&cast_regen<focus.deficit
				-- actions.careful_aim+=/barrage,if=active_enemies>1
				if GS.SCA(19434) then GS.Cast(nil, 19434, nil) return end -- aimed shot
				if GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target", interruptCasting) and GS.Hunter.FocusingShotThrottle == 0 and 50+(select(4, GetSpellInfo(152245))*0.001*focusregen) < GS.PP(true)-GS.PP() then GS.Cast("target", 152245, false, false, false, "SpellToInterrupt") return end -- focusing shot
				if GS.SCA(56641) then GS.Cast(nil, 56641, nil) return end -- steady shot
				return
			end
			-- actions+=/explosive_trap,if=active_enemies>1
			if GS.PlayerHasTalent(5, 1) and GS.SIR(131894) then GS.Cast(nil, 131894, nil) return end -- a murder of crows
			if GS.PlayerHasTalent(4, 2) and focusregen+(select(4, GetSpellInfo(19434))*0.001*focusregen) < GS.PP(true)-GS.PP() then GS.Cast("target", 19434, false, false, false, "SpellToInterrupt") return end -- dire beast
			if GS.PlayerHasTalent(6, 1) and GS.SIR(117050) then GS.Cast(nil, 117050, nil) return end -- glaive toss
			if GS.PlayerHasTalent(6, 2) and GS.SCA(109259, "target", interruptCasting) and select(4, GetSpellInfo(109259))*0.001*focusregen < GS.PP(true)-GS.PP() then GS.Cast("target", 109259, false, false, false, "SpellToInterrupt") return end -- powershot
			if GS.PlayerHasTalent(6, 3) and GS.SIR(120360) then GS.Cast(nil, 120360, nil) return end -- barrage
			if GS.CDs and GS.SCA(56641, "target") and (20*(select(4, GetSpellInfo(56641))*0.001)/(14+(focusregen*(select(4, GetSpellInfo(56641))*0.001)))) > GS.SpellCDDuration(3045, nil) then GS.Cast("target", 56641, nil) return end -- steady shot
			-- if GS.CDs and GS.SIR(3045) and GS.UnitIsBoss("target") then GS.Cast(nil, 3045, nil) return end -- rapid fire
			if GS.CDs and GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target", interruptCasting) and GS.Hunter.FocusingShotThrottle == 0 and (GS.PP(true)-GS.PP())*(select(4, GetSpellInfo(152245))*0.001)/(50+(select(4, GetSpellInfo(152245))*0.001)*focusregen) > GS.SpellCDDuration(3045, nil) and GS.PP() < 100 then GS.Cast("target", 152245, false, false, false, "SpellToInterrupt") return end -- focus shot rapid fire pooling
			if not GS.PlayerHasTalent(7, 2) and GS.SCA(56641, "target", interruptCasting) and GS.Hunter.PreSteadyFocus == 1 and (14+(select(4, GetSpellInfo(56641))*0.001*focusregen)+(select(4, GetSpellInfo(19434))*0.001*focusregen)) <= GS.PP(true)-GS.PP() then GS.Cast("target", 56641, false, false, false, "SpellToInterrupt") return end -- steady focus
			if GS.AoE and GS.SCA(2643, "target") and GS.TargetCount(8) > 6 then GS.Cast("target", 2643, nil) return end -- multishot
			if GS.PlayerHasTalent(7, 2) and GS.SCA(19434) then GS.Cast(nil, 19434, nil) return end -- aimed shot
			if GS.SCA(19434, "target") and (GS.PP()+(focusregen*(select(4, GetSpellInfo(56641))*0.001))) >= 85 then GS.Cast("target", 19434, nil) return end -- aimed shot
			if GS.SCA(19434, "target") and GS.Aura("player", 34720) and not GS.AuraRemaining("player", 34720, select(4, GetSpellInfo(56641))*0.001) and (GS.PP()+(focusregen*(select(4, GetSpellInfo(56641))*0.001))) >= 65 then GS.Cast("target", 19434, nil) return end -- aimed shot thrill of the hunt
			if GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target", interruptCasting) and GS.Hunter.FocusingShotThrottle == 0 and 40+(select(4, GetSpellInfo(152245))*0.001*focusregen) < GS.PP(true)-GS.PP() then GS.Cast("target", 152245, false, false, false, "SpellToInterrupt") return end -- focusing shot
			if GS.SCA(56641) then GS.Cast(nil, 56641, nil) return end -- steady shot
		end
	end

	function GS.HUNTER3() -- survival todo: finish implementing @hunter
		if GS.Combat() then
			local focusregen = GetPowerRegen()
			
			if GS.ValidTarget() then
				StartAttack("target")
				
				if GS.CDs then
					-- actions+=/use_item,name=beating_heart_of_the_mountain
					-- actions+=/arcane_torrent,if=focus.deficit>=30
					-- actions+=/blood_fury
					-- actions+=/berserking
					-- actions+=/potion,name=draenic_agility,if=(((cooldown.stampede.remains<1)&(cooldown.a_murder_of_crows.remains<1))&(trinket.stat.any.up|buff.archmages_greater_incandescence_agi.up))|target.time_to_die<=25
				end

				if GS.AoE and GS.TargetCount(8) > 1 then
					-- actions.aoe=stampede,if=buff.potion.up|(cooldown.potion.remains&(buff.archmages_greater_incandescence_agi.up|trinket.stat.any.up|buff.archmages_incandescence_agi.up))
					if GS.SCA(53301, "target", interruptCasting) and GS.Aura("player", 168980) and (not GS.PlayerHasTalent(6, 3) or GS.SpellCDDuration(120360, nil) > 0) then GS.Cast("target", 53301, false, false, false, "SpellToInterrupt") return end -- explosive shot dump
					-- actions.aoe+=/barrage
					if GS.SCA(3674, "target", interruptCasting) and not GS.Aura("target", 3674, "", "PLAYER") and (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] > 20 or GS.UnitIsBoss("target")) then GS.Cast("target", 3674, false, false, false, "SpellToInterrupt") return end -- black arrow
					if GS.SCA(53301, "target", interruptCasting) and GS.TargetCount(8) < 5 then GS.Cast("target", 53301, false, false, false, "SpellToInterrupt") return end -- explosive shot
					-- actions.aoe+=/explosive_trap,if=dot.explosive_trap.remains<=5
					if GS.PlayerHasTalent(5, 1) and GS.SCA(131894, "target", interruptCasting) then GS.Cast("target", 131894, false, false, false, "SpellToInterrupt") return end -- a murder of crows
					if GS.PlayerHasTalent(4, 2) and GS.SIR(120679) and not GS.IsCAOCH() then GS.Cast("target", 120679, false, false, false, "SpellToInterrupt") return end -- dire beast
					if GS.SCA(2643, "target", interruptCasting) and ((GS.Aura("player", 34720) and GS.PP() > 50 and focusregen <= GS.PP(true)-GS.PP()) or GS.AuraRemaining("target", 118253, 5, "", "PLAYER") or (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 4.5)) then GS.Cast("target", 2643, false, false, false, "SpellToInterrupt") return end -- multishot thrill of the hunt, serpent sting, execute
					if GS.PlayerHasTalent(6, 1) and GS.SCA(117050, "target", interruptCasting) then GS.Cast("target", 117050, false, false, false, "SpellToInterrupt") return end -- glaive toss
					-- actions.aoe+=/powershot
					if not GS.PlayerHasTalent(7, 2) and GS.SCA(77767, "target", interruptCasting) and GS.Hunter.PreSteadyFocus == 1 and GS.AuraRemaining("player", 177668, 5) and GS.PP()+14+(select(4, GetSpellInfo(77767))*0.001*focusregen) < 80 then GS.Cast("target", 77767, false, false, false, "SpellToInterrupt") return end -- cobra shot for steady focus
					if GS.SCA(2643, "target", interruptCasting) and (GS.PP() >= 70 or GS.PlayerHasTalent(7, 2)) then GS.Cast("target", 2643, false, false, false, "SpellToInterrupt") return end -- multi shot
					if GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target", interruptCasting) and GS.Hunter.FocusingShotThrottle == 0 then GS.Cast("target", 152245, false, false, false, "SpellToInterrupt") return end -- focusing shot
					if GS.SCA(77767) then GS.Cast("target", 77767, nil) return end -- cobra shot
					return
				end

				-- actions+=/stampede,if=buff.potion.up|(cooldown.potion.remains&(buff.archmages_greater_incandescence_agi.up|trinket.stat.any.up))|target.time_to_die<=25
				if GS.PlayerHasTalent(5, 1) and GS.SCA(131894, "target", interruptCasting) then GS.Cast("target", 131894, false, false, false, "SpellToInterrupt") return end -- a murder of crows
				if GS.SCA(3674, "target", interruptCasting) and not GS.Aura("target", 3674, "", "PLAYER") and (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] > 20 or GS.UnitIsBoss("target")) then GS.Cast("target", 3674, false, false, false, "SpellToInterrupt") return end -- black arrow
				if GS.SCA(53301, "target", interruptCasting) then GS.Cast("target", 53301, false, false, false, "SpellToInterrupt") return end -- explosive shot
				if GS.PlayerHasTalent(4, 2) and GS.SIR(120679) and not GS.IsCAOCH() then GS.Cast("target", 120679, false, false, false, "SpellToInterrupt") return end -- dire beast
				if GS.SCA(3044, "target", interruptCasting) and ((GS.Aura("player", 34720) and GS.PP() > 35 and focusregen <= GS.PP(true)-GS.PP()) or GS.AuraRemaining("target", 118253, 3, "", "PLAYER") or (GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 4.5)) then GS.Cast("target", 3044, false, false, false, "SpellToInterrupt") return end -- arcane shot execute, serpent sting, thrill of the hunt
				if not GS.Aura("player", 77769) and GS.SIR(77769) then GS.Cast("target", 77769, false, false, false, "SpellToInterrupt") return end -- trap launcher
				if GS.SIR(82939) and GetUnitSpeed("target") == 0 then GS.Cast("target", 82939, false, false, false, "SpellToInterrupt") return end -- explosive trap
				if not GS.PlayerHasTalent(7, 2) and GS.SCA(77767, "target", interruptCasting) and GS.Hunter.PreSteadyFocus == 1 and GS.AuraRemaining("player", 177668, 5) and (14+(select(4, GetSpellInfo(77767))*0.001*focusregen)) <= GS.PP(true)-GS.PP() and GS.PP(true)-GS.PP() < 80 then GS.Cast("target", 77767, false, false, false, "SpellToInterrupt") return end -- steady focus
				if GS.SCA(3044, "target", interruptCasting) and (GS.PP() >= 80 or GS.PlayerHasTalent(7, 2)) then GS.Cast("target", 3044, false, false, false, "SpellToInterrupt") return end -- arcane shot
				if GS.PlayerHasTalent(7, 2) and GS.SCA(152245, "target", interruptCasting) then GS.Cast("target", 152245, false, false, false, "SpellToInterrupt") return end -- focusing shot
				if not GS.PlayerHasTalent(7, 2) and GS.SCA(77767) then GS.Cast("target", 77767, nil) return end -- cobra shot
			end
		end
	end

	function GS.HUNTER3PVP() -- todo: don't forget about this @pvp @hunter
		if GS.Combat() and GS.ValidTarget() then
			StartAttack("target")
		end
		-- actions+=/use_item,name=beating_heart_of_the_mountain
		-- actions+=/arcane_torrent,if=focus.deficit>=30
		-- actions+=/blood_fury
		-- actions+=/berserking
		-- actions+=/potion,name=draenic_agility,if=(((cooldown.stampede.remains<1)&(cooldown.a_murder_of_crows.remains<1))&(trinket.stat.any.up|buff.archmages_greater_incandescence_agi.up))|target.time_to_die<=25
		-- actions+=/call_action_list,name=aoe,if=active_enemies>1
		-- actions+=/stampede,if=buff.potion.up|(cooldown.potion.remains&(buff.archmages_greater_incandescence_agi.up|trinket.stat.any.up))|target.time_to_die<=25
		-- actions+=/a_murder_of_crows
		-- actions+=/black_arrow,if=!ticking
		-- actions+=/explosive_shot
		-- actions+=/dire_beast
		-- actions+=/arcane_shot,if=buff.thrill_of_the_hunt.react&focus>35&cast_regen<=focus.deficit|dot.serpent_sting.remains<=3|target.time_to_die<4.5
		-- actions+=/explosive_trap
		-- # Cast a second shot for steady focus if that won't cap us.
		-- actions+=/cobra_shot,if=buff.pre_steady_focus.up&buff.steady_focus.remains<5&(14+cast_regen)<=focus.deficit<80
		-- actions+=/arcane_shot,if=focus>=80|talent.focusing_shot.enabled
		-- actions+=/focusing_shot
		-- actions+=/cobra_shot

		-- actions.aoe=stampede,if=buff.potion.up|(cooldown.potion.remains&(buff.archmages_greater_incandescence_agi.up|trinket.stat.any.up|buff.archmages_incandescence_agi.up))
		-- actions.aoe+=/explosive_shot,if=buff.lock_and_load.react&(!talent.barrage.enabled|cooldown.barrage.remains>0)
		-- actions.aoe+=/barrage
		-- actions.aoe+=/black_arrow,if=!ticking
		-- actions.aoe+=/explosive_shot,if=active_enemies<5
		-- actions.aoe+=/explosive_trap,if=dot.explosive_trap.remains<=5
		-- actions.aoe+=/a_murder_of_crows
		-- actions.aoe+=/dire_beast
		-- actions.aoe+=/multishot,if=buff.thrill_of_the_hunt.react&focus>50&cast_regen<=focus.deficit|dot.serpent_sting.remains<=5|target.time_to_die<4.5
		-- actions.aoe+=/glaive_toss
		-- actions.aoe+=/powershot
		-- actions.aoe+=/cobra_shot,if=buff.pre_steady_focus.up&buff.steady_focus.remains<5&focus+14+cast_regen<80
		-- actions.aoe+=/multishot,if=focus>=70|talent.focusing_shot.enabled
		-- actions.aoe+=/focusing_shot
		-- actions.aoe+=/cobra_shot		
	end

	function GS.ROGUE1() -- assassination todo: implement @rogue
		if not GS.RogueBOS and GS.SIR(108212) and GS.Aura("player", 1784) and GS.Aura("player", 137573) and GS.AuraRemaining("player", 137573, 0.2) then
			GS.Cast("player", 108212, nil)
			GS.RogueBOS = true
		end -- burst of speed
		if GS.SIR(2823) and not IsMounted() and not GS.Aura("player", 2823) and not GS.Aura("player", 157584) then GS.Cast("player", 2823, nil) return end -- lethal poison

		if GS.Combat() then
			GS.MultiDoT("Deadly Poison")
			GS.MultiDoT("Rupture")
			GS.MultiDoT("Crimson Tempest")

			local cp = GetComboPoints("player")
			local activeEnemies = #GS.PullEnemies(100, true)

			if GS.ValidTarget() then
				if GSR.Interrupt then GS.Interrupt() end

				-- actions=potion,name=draenic_agility,if=buff.bloodlust.react|target.time_to_die<40|debuff.vendetta.up
				
				if GS.CDs then
					if GS.SIR(14185) and not GS.Aura("player", 115193) and GS.SpellCDDuration(1856, nil) > 60 then GS.Cast("target", 14185, false, false, false, "SpellToInterrupt") return end -- preparation

					-- actions+=/use_item,slot=trinket2,if=active_enemies>1|(debuff.vendetta.up&active_enemies=1)
					-- actions+=/blood_fury
					-- actions+=/berserking
					if GSR.Race == "BloodElf" and GS.SIR(25046) and GS.PP() < 60 then GS.Cast("target", 25046, false, false, false, "SpellToInterrupt") return end -- arcane torrent

					if GS.SIR(1856) and (GetTime()-GS.CombatStart) > 10 and not IsStealthed() and not GS.Aura("player", 115193) and IsInGroup() then GS.Cast("target", 1856, false, false, false, "SpellToInterrupt") return end -- vanish
				end

				if GS.SIR(1943) and cp == 5 then -- rupture
					if GS.SCA(1943, "target", interruptCasting) and GS.AuraRemaining("target", 1943, 6, "", "PLAYER") then GS.Cast("target", 1943, false, false, false, "SpellToInterrupt") return
					elseif GS.AoE and activeEnemies > 1 then
						for i = 1, #tNoObjectRupture do
							if GS.SCA(1943, tNoObjectRupture[i], interruptCasting) then GS.Cast(tNoObjectRupture[i], 1943, false, false, false, "SpellToInterrupt") return end
						end
					end
				end

				if GS.SCA(1329, "target", interruptCasting) and (IsStealthed() or GS.Aura("player", 115192)) then GS.Cast("target", 1329, false, false, false, "SpellToInterrupt") return end -- mutilate stealthed
				-- if GS.SIR(5171) and GS.AuraRemaining("player", 5171, 5) then GS.Cast("target", 5171, false, false, false, "SpellToInterrupt") return end -- slice and dice
				if GS.PlayerHasTalent(6, 2) and cp == 0 and GS.SIR(137619) then 
					if not GS.AoE then
						GS.Cast("target", 137619, false, false, false, "SpellToInterrupt")
					else
						lowestMob, maxHP = nil, math.huge
						for i = 1, #GS.Targets do
							if GS.Health(GS.Targets[i], false, false) < maxHP and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) then
								lowestMob = GS.Targets[i]
								maxHP = GS.Health(GS.Targets[i], maxhealth, percenthealth)
							end
						end
						GS.Cast(lowestMob, 137619, false, false, false, "SpellToInterrupt")
					end
					return
				end -- marked for death
				if GS.AoE and activeEnemies >= 4 and cp == 5 and GS.SIR(121411) then -- crimson tempest
					for i = 1, #tNoObjectCrimsonTempest do
						if GS.Distance(tNoObjectCrimsonTempest[i], nil) <= 10+UnitCombatReach(tNoObjectCrimsonTempest[i]) then GS.Cast("player", 121411, false, false, false, "SpellToInterrupt") return end
					end
				end
				if GS.AoE and GS.SIR(51723) and GS.PlayerCount(10) >= 4 then GS.Cast("target", 51723, false, false, false, "SpellToInterrupt") return end -- fan of knives aoe
				if GS.SIR(1943) and ((GS.AuraRemaining("target", 1943, 2, "", "PLAYER")) or (cp == 5 and GS.AuraRemaining("target", 1943, 7.2, "", "PLAYER"))) and (activeEnemies == 1 or not GS.AoE) then GS.Cast("target", 1943, false, false, false, "SpellToInterrupt") return end -- rupture
				if GS.CDs and GS.PlayerHasTalent(7, 2) and GS.SpellCDDuration(79140, nil) == 0 and GS.SIR(152151) then GS.Cast("target", 152151, false, false, false, "SpellToInterrupt") return end -- shadow reflection vendetta up
				if GS.CDs and GS.UnitIsBoss("target") and GS.SIR(79140) and (not GS.PlayerHasTalent(7, 2) or GS.Aura("player", 152151)) then GS.Cast("target", 79140, false, false, false, "SpellToInterrupt") return end -- vendetta
				if GS.PlayerHasTalent(7, 3) and GS.SCA(152150, "target", interruptCasting) and cp > 4 then GS.Cast("target", 152150, false, false, false, "SpellToInterrupt") return end -- death from above
				if (activeEnemies < 4 or not GS.AoE) and GS.SIR(32645) and cp == 5  and (not GS.PlayerHasTalent(7, 3) or GS.SpellCDDuration(152150, nil) > 2) then -- envenom
					if GS.SCA(32645, "target", interruptCasting) and not GS.Aura("target", 2818, "", "PLAYER") then GS.Cast("target", 32645, false, false, false, "SpellToInterrupt") return
					elseif GS.AoE then
						for i = 1, #tNoObjectDeadlyPoison do
							if GS.SCA(32645, tNoObjectDeadlyPoison[i], interruptCasting) then GS.Cast(tNoObjectDeadlyPoison[i], 32645, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(32645, "target", interruptCasting) and (GS.AuraRemaining("player", 32645, 1.8) or GS.PP() > 55) then GS.Cast("target", 32645, false, false, false, "SpellToInterrupt") return end
				end
				if GS.AoE and activeEnemies > 2 and GS.SIR(51723) and GS.SpellCDDuration(79140, nil) < 100 then -- fan of knives
					for i = 1, #tNoObjectDeadlyPoison do
						if GS.Distance(tNoObjectDeadlyPoison[i], nil) <= 10+UnitCombatReach(tNoObjectDeadlyPoison[i]) then GS.Cast("player", 51723, false, false, false, "SpellToInterrupt") return end
					end
				elseif GS.AoE and activeEnemies == 2 and (cp < 4 or GS.PlayerHasTalent(6, 3) and not GS.AuraStacks("player", 115189, 3)) and GS.SIR(1329) and GS.SpellCDDuration(79140, nil) < 100 then -- mutilate cp builder spread poisons cleave
					if GS.SCA(1329, "target", interruptCasting) and GS.Health("target", maxhealth, true) > 35 and not GS.Aura("target", 2818, "", "PLAYER") then GS.Cast("target", 1329, false, false, false, "SpellToInterrupt") return
					else
						for i = 1, #tNoObjectDeadlyPoison do
							if GS.SCA(1329, tNoObjectDeadlyPoison[i], interruptCasting) and GS.Health(tNoObjectDeadlyPoison[i], maxhealth, true) > 35 then GS.Cast(tNoObjectDeadlyPoison[i], 1329, false, false, false, "SpellToInterrupt") return end
						end
					end
				end
				if GS.SCA(1329, "target", interruptCasting) and GS.Health("target", maxhealth, true) > 35 and (cp < 4 or GS.PlayerHasTalent(6, 3) and not GS.AuraStacks("player", 115189, 3)) and (activeEnemies < 5 or not GS.AoE) then GS.Cast("target", 1329, false, false, false, "SpellToInterrupt") return end -- mutilate non execute cp builder non aoe
				if GS.SpellCDDuration(111240, nil) == 0 and (cp < 5 or (GS.PlayerHasTalent(6, 3) and not GS.AuraStacks("player", 115189, 4))) then -- dispatch
					if GS.AoE and activeEnemies == 2 and GS.SpellCDDuration(79140, nil) < 100 then
						if GS.SCA(111240, "target", interruptCasting) and not GS.Aura("target", 2818, "", "PLAYER") then GS.Cast("target", 111240, false, false, false, "SpellToInterrupt") return
						else
							for i = 1, #tNoObjectDeadlyPoison do
								if GS.SCA(111240, tNoObjectDeadlyPoison[i], interruptCasting) then GS.Cast(tNoObjectDeadlyPoison[i], 111240, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SCA(111240, "target", interruptCasting) and (activeEnemies < 4 or not GS.AoE) then GS.Cast("target", 111240, false, false, false, "SpellToInterrupt") return end
				end
				if GS.AoE and GS.SIR(1329) and activeEnemies == 2 and GS.SpellCDDuration(79140, nil) < 100 then -- mutilate spread poisons
					if GS.SCA(1329, "target", interruptCasting) and not GS.Aura("target", 2818, "", "PLAYER") then GS.Cast("target", 1329, false, false, false, "SpellToInterrupt") return
					elseif GS.AoE then
						for i = 1, #tNoObjectDeadlyPoison do
							if GS.SCA(1329, tNoObjectDeadlyPoison[i], interruptCasting) then GS.Cast(tNoObjectDeadlyPoison[i], 1329, false, false, false, "SpellToInterrupt") return end
						end
					end
				end
				if GS.SCA(1329, "target", interruptCasting) and (activeEnemies < 5 or not GS.AoE) then GS.Cast("target", 1329, false, false, false, "SpellToInterrupt") return end -- mutilate
			end
		end
	end

	function GS.ROGUE2() -- combat -- todo: add preparation vanish marked for death @rogue, onuse trinkets, orc cooldown
		if not GS.RogueBOS and GS.SIR(108212) and GS.Aura("player", 1784) and GS.Aura("player", 137573) and GS.AuraRemaining("player", 137573, 0.2) then
			GS.Cast("player", 108212, nil)
			GS.RogueBOS = true
		end -- burst of speed

		if GS.SIR(2823) and not IsMounted() and not GS.Aura("player", 2823) and not GS.Aura("player", 157584) then GS.Cast("player", 2823, nil) return end -- lethal poison
		if GS.Combat() then
			local cp = GetComboPoints("player")
			GS.MultiDoT("Crimson Tempest")

			if GS.ValidTarget() then
				StartAttack("target")
				-- actions=potion,name=draenic_agility,if=buff.bloodlust.react|target.time_to_die<40|(buff.adrenaline_rush.up&(trinket.proc.any.react|trinket.stacking_proc.any.react|buff.archmages_greater_incandescence_agi.react))
				-- actions+=/preparation,if=!buff.vanish.up&cooldown.vanish.remains>30
				-- actions+=/use_item,slot=trinket2
				-- actions+=/blood_fury
				if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) and GS.UnitIsBoss("target") then GS.Cast("target", 26297, nil) return end -- berserking
				if GS.CDs and GS.PP() < 60 and GS.SIR(25046) then GS.Cast("target", 25046, nil) return end -- arcane torrent
				if GS.SIR(13877) and ((GS.AoE and GS.PlayerCount(5) >= 2 and not GS.Aura("player", 13877))) then GS.Cast("player", 13877, nil) return -- blade flurry
				elseif ((not GS.AoE or GS.PlayerCount(5) < 2) and GS.Aura("player", 13877)) then CancelUnitBuff("Blade Flurry") return end -- cancel blade flurry
				if GS.PlayerHasTalent(7, 2) and GS.CDs and GS.SIR(152151) and (GS.Aura("player", 13750) or (cp > 3 and GS.SpellCDDuration(51690, nil) < 10)) then GS.Cast("target", 152151, false, false, false, "SpellToInterrupt") return end -- shadow reflection
				if GS.SCA(8676) then GS.Cast("target", 8676, nil) return end -- ambush

				-- actions+=/vanish,if=time>10&(combo_points<3|(talent.anticipation.enabled&anticipation_charges<3)|(combo_points<4|(talent.anticipation.enabled&anticipation_charges<4)))&((talent.shadow_focus.enabled&buff.adrenaline_rush.down&energy<90&energy>=15)|(talent.subterfuge.enabled&energy>=90)|(!talent.shadow_focus.enabled&!talent.subterfuge.enabled&energy>=60))
				if GS.SIR(5171) and (GetTime()-GS.CombatStart) > 10 and (GS.AuraRemaining("player", 5171, 2) or (GS.TTD[ObjectPointer("target")] > 45 and cp == 5 and GS.AuraRemaining("player", 5171, 12) and not GS.Aura("player", 84747))) then GS.Cast("target", 5171, false, false, false, "SpellToInterrupt") return end -- slice and dice

				if GS.CDs and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.SIR(13750) and GS.SpellCDDuration(51690, nil) > 10 then
					if GS.TTD[ObjectPointer("target")] >= 44 then GS.Cast("target", 13750, false, false, false, "SpellToInterrupt") return end -- you have enough time to use it again
					-- actions.adrenaline_rush+=/adrenaline_rush,if=time_to_die<44&buff.archmages_greater_incandescence_agi.react&buff.archmages_greater_incandescence_agi.remains>=buff.adrenaline_rush.duration
					if GS.TTD[ObjectPointer("target")] < 44 and GS.Aura("player", 126554) and not GS.AuraRemaining("player", 126554, 15) then GS.Cast("target", 13750, false, false, false, "SpellToInterrupt") return end
						-- actions.adrenaline_rush+=/adrenaline_rush,if=time_to_die<44&trinket.proc.any.react&trinket.proc.any.remains>=buff.adrenaline_rush.duration
					if GS.TTD[ObjectPointer("target")] <= 22.5 then GS.Cast("target", 13750, false, false, false, "SpellToInterrupt") return end -- boss is about to die just use it
				end

				if GS.CDs and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.SIR(51690) and (GS.PP()<40 or GS.Bloodlust(20) and (GetTime()-GS.CombatStart) < 10) and not GS.Aura("player", 13750) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152151, nil)>30 or not GS.AuraRemaining("player", 152151, 3)) then
					if GS.TTD[ObjectPointer("target")] >= 44 then GS.Cast("target", 51690, false, false, false, "SpellToInterrupt") return end -- you have enough time to use it again
					-- actions.killing_spree+=/killing_spree,if=time_to_die<44&buff.archmages_greater_incandescence_agi.react&buff.archmages_greater_incandescence_agi.remains>=buff.killing_spree.duration
					if GS.TTD[ObjectPointer("target")] < 44 and GS.Aura("player", 126554) and not GS.AuraRemaining("player", 126554, 3) then GS.Cast("target", 51690, false, false, false, "SpellToInterrupt") return end
						-- actions.killing_spree+=/killing_spree,if=time_to_die<44&trinket.proc.any.react&trinket.proc.any.remains>=buff.killing_spree.duration
					if GS.TTD[ObjectPointer("target")] < 44 and GS.Aura("player", 177067) and not GS.AuraRemaining("player", 177067, 3) then GS.Cast("target", 51690, false, false, false, "SpellToInterrupt") return end -- humming blackiron trigger
					if GS.TTD[ObjectPointer("target")] <= 4.5 then GS.Cast("target", 51690, false, false, false, "SpellToInterrupt") return end -- boss is about to die just use it
				end

				if GS.PlayerHasTalent(6, 2) and GS.SIR(137619) and cp <= 1 and GS.Aura("target", 84617, "", "PLAYER") and (not GS.PlayerHasTalent(7, 2) or GS.Aura("player", 152151) or GS.SpellCDDuration(152151, nil) > 30) then
					if not GS.AoE then
						GS.Cast("target", 137619, false, false, false, "SpellToInterrupt")
					else
						lowestMob, maxHP = nil, math.huge
						for i = 1, #GS.Targets do
							if GS.Health(GS.Targets[i], false, false) < maxHP and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) then
								lowestMob = GS.Targets[i]
								maxHP = GS.Health(GS.Targets[i], maxhealth, percenthealth)
							end
						end
						GS.Cast(lowestMob, 137619, false, false, false, "SpellToInterrupt")
					end
					return
				end -- marked for death

				if cp < 5 or (GS.PlayerHasTalent(6, 3) and not GS.AuraStacks("player", 115189, 3) and not GS.Aura("player", 84747)) then
					if GS.SCA(84617) and GS.AuraRemaining("target", 84617, 6, "", "PLAYER") then GS.Cast("target", 84617, nil) return end -- revealing strike
					if GS.SCA(1752) then GS.Cast("target", 1752, nil) return end -- sinister strike
				end

				if cp == 5 and (GS.Aura("player", 84747) or not GS.PlayerHasTalent(6, 3) or (GS.PlayerHasTalent(6, 3) and GS.AuraStacks("player", 115189, 3))) then
					if GS.PlayerHasTalent(7, 3) and GS.SCA(152150, "target", interruptCasting) then GS.Cast("target", 152150, false, false, false, "SpellToInterrupt") return end -- dfa
					if GS.SCA(2098) and (not GS.PlayerHasTalent(7, 3) or GS.SpellCDDuration(152150, nil) > 0) then GS.Cast("target", 2098, nil) return end -- eviscerate
				end
			end
		end
	end

	local tierbonuspool
	function GS.ROGUE3() -- subtlety todo: general updates, figure out how to check cost type for spells @rogue @pooling
		if not GS.RogueBOS and GS.SIR(108212) and GS.Aura("player", 1784) and GS.Aura("player", 137573) and GS.AuraRemaining("player", 137573, 0.2) then
			GS.Cast("player", 108212, nil)
			GS.RogueBOS = true
		end -- burst of speed

		if GS.SIR(2823) and not IsMounted() and not GS.Aura("player", 2823) then GS.Cast("player", 2823, nil) return end -- lethal poison
		if GS.Combat() then
			local focusregen = GetPowerRegen()
			local focustimetomax = (120-GS.PP())/focusregen
			local cp = GetComboPoints("player")
			GS.MultiDoT("Rupture")
			GS.MultiDoT("Crimson Tempest")
			if GS.TierBonus("t17") >= 2 then
				tierbonuspool = 50
			else
				tierbonuspool = 0
			end
			if GS.ValidTarget() then
				StartAttack("target")
				if GS.CDs and GS.Aura("player", 51713) then
					if GS.CDs and GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 and GS.Aura("player", 51713) then UseInventoryItem(13) end
					if GS.CDs and GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 and GS.Aura("player", 51713) then UseInventoryItem(14) end
					if GS.PlayerHasTalent(7, 2) and GS.CDs and GS.SIR(152151) and GS.Aura("player", 51713) then GS.Cast("target", 152151, false, false, false, "SpellToInterrupt") return end -- shadow reflection
					if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) and GS.Aura("player", 51713) then GS.Cast("player", 20572, nil) end -- blood fury
					if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) and GS.Aura("player", 51713) then GS.Cast("player", 26297, nil) end -- berserking
					if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(25046) and GS.PP() < 60 then GS.Cast("player", 25046, nil) end -- arcane torrent
				end

				if GS.SIR(14183) and cp <= 4 and ((not (cp > 1 and GS.PP() > 100 and GS.Aura("player", 51713)) and not GS.Aura("player", 115192)) or (GS.Aura("player", 115192) and GS.Aura("target", 91021, "", "PLAYER"))) and (GetTime()-GS.CombatStart) > 9 then GS.Cast("target", 14183, false, false, false, "SpellToInterrupt") return end -- premeditation

				-- actions+=/wait,sec=buff.subterfuge.remains-0.1,if=buff.subterfuge.remains>0.5&buff.subterfuge.remains<1.6&time>6

				if GS.CDs and GS.SIR(51713) and ((GS.PP() >= 50 and not GS.Aura("player", 11327) and not GS.Aura("player", 1784) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER")) or (GS.Bloodlust() and (GS.Aura("target", 16511, "", "PLAYER") or GS.Aura("target", 703, "", "PLAYER") or GS.Aura("target", 1943, "", "PLAYER")))) then GS.Cast("player", 51713, false, false, false, "SpellToInterrupt") return end -- shadow dance
				if GS.CDs and GS.SIR(51713) and not GS.Aura("player", 11327) and not GS.Aura("player", 1784) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER") and GS.PP() < 50 and not (GS.Bloodlust() and (GS.Aura("target", 16511, "", "PLAYER") or GS.Aura("target", 703, "", "PLAYER") or GS.Aura("target", 1943, "", "PLAYER"))) then return end -- pool for shadow dance

				if GS.PlayerHasTalent(1, 3) and GS.CDs and IsInGroup() and GS.SIR(1856) and GS.PP() < 45 and (cp < 4 or (GS.PlayerHasTalent(6, 3) and (not GS.Aura("player", 115189) or cp+select(4, GS.Aura("player", 115189)) < 9))) and not GS.Aura("player", 51713) and not GS.Aura("player", 31665) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER") then return end -- vanish pool
				if GS.PlayerHasTalent(1, 3) and GS.CDs and IsInGroup() and GS.SIR(1856) and GS.PP() >= 45 and GS.PP() <= 75 and (cp < 4 or (GS.PlayerHasTalent(6, 3) and (not GS.Aura("player", 115189) or cp+select(4, GS.Aura("player", 115189)) < 9))) and not GS.Aura("player", 51713) and not GS.Aura("player", 31665) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER") then GS.Cast("player", 1856, false, false, false, "SpellToInterrupt") return end -- vanish

				-- actions+=/pool_resource,for_next=1,extra_amount=50
				-- actions+=/shadowmeld,if=talent.shadow_focus.enabled&energy>=45&energy<=75&(combo_points<4|(talent.anticipation.enabled&combo_points+anticipation_charges<9))&buff.shadow_dance.down&buff.master_of_subtlety.down&debuff.find_weakness.remains<2

				if GS.PlayerHasTalent(1, 2) and GS.CDs and IsInGroup() and GS.SIR(1856) and GS.PP() < 90 and (cp < 4 or (GS.PlayerHasTalent(6, 3) and (not GS.Aura("player", 115189) or cp+select(4, GS.Aura("player", 115189)) < 9))) and not GS.Aura("player", 51713) and not GS.Aura("player", 31665) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER") then return end -- vanish pool
				if GS.PlayerHasTalent(1, 2) and GS.CDs and IsInGroup() and GS.SIR(1856) and GS.PP() >= 90 and (cp < 4 or (GS.PlayerHasTalent(6, 3) and (not GS.Aura("player", 115189) or cp+select(4, GS.Aura("player", 115189)) < 9))) and not GS.Aura("player", 51713) and not GS.Aura("player", 31665) and GS.AuraRemaining("target", 91021, 2, "", "PLAYER") then GS.Cast("player", 1856, false, false, false, "SpellToInterrupt") return end -- vanish

				-- actions+=/shadowmeld,if=talent.subterfuge.enabled&energy>=90&(combo_points<4|(talent.anticipation.enabled&combo_points+anticipation_charges<9))&buff.shadow_dance.down&buff.master_of_subtlety.down&debuff.find_weakness.remains<2

				if GS.PlayerHasTalent(6, 2) and GS.SIR(137619) and cp == 0 then -- marked for death
					if not GS.AoE then
						GS.Cast("target", 137619, false, false, false, "SpellToInterrupt")
					else
						lowestMob, maxHP = nil, math.huge
						for i = 1, #GS.Targets do
							if GS.Health(GS.Targets[i], false, false) < maxHP and (UnitIsTappedByPlayer(GS.Targets[i]) or tContains(GS.Dummies, UnitName(GS.Targets[i]))) then
								lowestMob = GS.Targets[i]
								maxHP = GS.Health(GS.Targets[i], maxhealth, percenthealth)
							end
						end
						GS.Cast(lowestMob, 137619, false, false, false, "SpellToInterrupt")
					end
					return
				end

				if cp == 5 then
					local activeEnemies = GS.PlayerCount(10)

					if GS.SIR(1943) and ((not GS.PlayerHasTalent(7, 3) or GS.SpellCDDuration(152150, nil) > 0) or (c)) then -- rupture
						if GS.SCA(1943, "target", interruptCasting) and (not GS.Aura("target", 1943, "", "PLAYER") or GS.AuraRemaining("target", 1943, 7.2, "", "PLAYER") or (not GS.AuraRemaining("player", 152151, 8) and GS.AuraRemaining("player", 152151, 12) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 8)) then
							GS.Cast("target", 1943, false, false, false, "SpellToInterrupt")
							return
						elseif GS.AoE then
							for i = 1, #tNoObjectRupture do
								if GS.SCA(1943, tNoObjectRupture[i], interruptCasting) then GS.Cast(tNoObjectRupture[i], 1943, false, false, false, "SpellToInterrupt") return end
							end
							for i = 1, #tRupture do
								if GS.SCA(1943, tRupture[i], interruptCasting) and (GS.AuraRemaining(tRupture[i], 1943, 7.2, "", "PLAYER") or (not GS.AuraRemaining("player", 152151, 8) and GS.AuraRemaining("player", 152151, 12) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 8)) then GS.Cast(tRupture[i], 1943, false, false, false, "SpellToInterrupt") return end
							end
						end
					end

					if GS.AuraRemaining("player", 5171, 10.8) and (GetNumArenaOpponents() > 0 or GS.AuraRemaining("player", 5171, GS.TTD[ObjectPointer("target")])) then GS.Cast("player", 5171, false, false, false, "SpellToInterrupt") return end -- slice and dice

					if GS.PlayerHasTalent(7, 3) and GS.SCA(152150, "target", interruptCasting) then GS.Cast("target", 152150, false, false, false, "SpellToInterrupt") return end -- death from above

					if GS.AoE and GS.SIR(121411) and activeEnemies >= 3 then -- crimson tempest
						if activeEnemies >= 5 and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152150, nil) > 0) then GS.Cast("target", 121411, false, false, false, "SpellToInterrupt") return end -- crimson tempest
						for i = 1, #tNoObjectCrimsonTempest do
							if GS.Distance(tNoObjectCrimsonTempest[i], nil) <= 10 then GS.Cast(tNoObjectCrimsonTempest[i], 121411, false, false, false, "SpellToInterrupt") return end
						end
						for i = 1, #tCrimsonTempest do
							if GS.AuraRemaining(tCrimsonTempest[i], 122233, 4) and GS.Distance(tCrimsonTempest[i], nil) <= 10 then GS.Cast("target", 121411, false, false, false, "SpellToInterrupt") return end
						end
					end

					if GS.SCA(2098, "target", interruptCasting) and (not GS.PlayerHasTalent(7, 3) or (focustimetomax <= GS.SpellCDDuration(152150, nil)+1--[[action.death_from_above.execute_time]])) then GS.Cast("target", 2098, false, false, false, "SpellToInterrupt") return end -- eviscerate
					if GS.CDs and GS.SIR(14185) and not GS.Aura("player", 11327) and GS.SpellCDDuration(1856, nil) > 60 then GS.Cast("player", 14185, false, false, false, "SpellToInterrupt") return end -- preparation pool
					return
				end

				if cp < 4 or (cp == 4 and GS.SpellCDDuration(51699, nil) > 1 and GS.PP() > 70-focusregen) or (GS.PlayerHasTalent(6, 3) and not GS.AuraStacks("player", 115189, 4)) then

					if not GS.Aura("player", 31665) and not GS.Aura("player", 51713) and not GS.Aura("target", 91021, "", "PLAYER") and ((GS.PP()+tierbonuspool+GS.SpellCDDuration(51713, nil)*focusregen) <= GS.PP(true) or (GS.PP()+GS.SpellCDDuration(1856, nil)*focusregen) <= GS.PP(true)) then
						if GS.CDs and GS.SIR(14185) and not GS.Aura("player", 11327) and GS.SpellCDDuration(1856, nil) > 60 then GS.Cast("player", 14185, false, false, false, "SpellToInterrupt") return end -- preparation pool
					end
					if GS.SpellCDDuration(61304, nil) == 0 and GS.PoolCheck(8676) then return end -- pool for ambush
					if GS.SCA(8676, "target", interruptCasting) then GS.Cast("target", 8676, false, false, false, "SpellToInterrupt") return end -- ambush

					if GS.AoE and GS.SIR(51723) and GS.PlayerCount(10) > 1 then GS.Cast("target", 51723, false, false, false, "SpellToInterrupt") return end -- fan of knives
					if GS.SCA(16511, "target", interruptCasting) and ((not GS.PlayerIsBehind("target")) or (not GS.Aura("target", 16511, "", "PLAYER")) or (GS.AuraRemaining("target", 16511, 7.2, "", "PLAYER") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] >= (select(7, GS.Aura("target", 16511, "", "PLAYER"))-GetTime())+24+8 and not GS.Aura("target", 91021, "", "PLAYER"))) then GS.Cast("target", 16511, false, false, false, "SpellToInterrupt") return end
					if GS.PlayerHasTalent(6, 1) and GS.PP() < 65 and focusregen < 16 and GS.SCA(114014, "target", interruptCasting) then GS.Cast("target", 114014, false, false, false, "SpellToInterrupt") return end -- shuriken toss
					if GS.SCA(53, "target", interruptCasting) and GS.PlayerIsBehind("target") then GS.Cast("target", 53, false, false, false, "SpellToInterrupt") return end -- backstab
				end

				if GS.CDs and GS.SIR(14185) and not GS.Aura("player", 11327) and GS.SpellCDDuration(1856, nil) > 60 then GS.Cast("player", 14185, false, false, false, "SpellToInterrupt") return end -- preparation pool
			end
		end
	end

	function GS.PRIEST1() -- disc
		if GS.SIR(21562) and not GS.Combat() and not IsMounted() and not GetRaidBuffTrayAuraInfo(2) then GS.Cast("player", 21562, nil) return end -- stamina
		if GS.Combat() and not GS.IsCAOCH() then
			
			for k,v in ipairs(GS.Players[tanksIndex].Players) do -- pw: shield the tanks
				if GS.SCA(17, v.Player, interruptCasting) then
					GS.Cast(v.Player, 17, false, false, false, "SpellToInterrupt")
					return
				end
			end

			if IsAltKeyDown() and UnitExists("mouseover") and GS.SCA(17, "mouseover", interruptCasting) then -- power word shield mouseover
				GS.Cast("mouseover", 17, false, false, false, "SpellToInterrupt")
				return
			end

			if GS.SIR(47540) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > 2/(1+GetHaste()*.01)) then -- penance
				local healing = GS.PriestHealing("Penance")

				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end

					if GS.SCA(47540, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 47540, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end

					if GS.SCA(47540, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 47540, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end

					if GS.SCA(47540, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 47540, false, false, false, "SpellToInterrupt") return end
				end

				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
						if GS.SCA(47540, v.Player, interruptCasting) and v.Stats.HealthRemaining >= healing then GS.Cast(v.Player, 47540, false, false, false, "SpellToInterrupt") return end
					end
				end
			end


			if GS.SCA(585, "target", interruptCasting) then GS.Cast("target", 585, false, false, false, "SpellToInterrupt") return end -- smite
		end
	end

	function GS.PRIEST3() -- shadow todo: make a channeling manager for shadow priest, affliction warlock, frost mage(?)
		if GS.SIR(21562) and not IsMounted() and not GetRaidBuffTrayAuraInfo(2) then GS.Cast("player", 21562, nil) return end -- stamina
		if GS.SIR(15473) and not GS.Aura("player", 15473) then GS.Cast("player", 15473, nil) return end -- shadow form
		if not GS.PlayerHasTalent(7, 3) and GS.Priest.Apparitions > 0 then GS.Priest.Apparitions = 0 end
		if GS.Combat() then
			for i = 1, #GS.Targets do
				if not GS.Priest.VampiricTouchThrottle[UnitGUID(GS.Targets[i])] then GS.Priest.VampiricTouchThrottle[UnitGUID(GS.Targets[i])] = 0 end
				if not GS.Priest.MindHarvest[UnitGUID(GS.Targets[i])] then GS.Priest.MindHarvest[UnitGUID(GS.Targets[i])] = 0 end
			end

			GS.MultiDoT("Devouring Plague")
			GS.MultiDoT("Shadow Word: Pain")
			GS.MultiDoT("Vampiric Touch")
			if GS.PlayerHasTalent(7, 2) then GS.MultiDoT("Void Entropy") end
			if GS.ValidTarget() then
				if GSR.Thok and UnitChannelInfo("player") and ThokThrottle > GetTime() and ThokThrottle-GetTime() <= 0.2 then SpellStopCasting() end

				-- actions+=/potion,name=draenic_intellect,if=buff.bloodlust.react|target.time_to_die<=40
				-- if GS.CDs and 
				-- actions+=/power_infusion,if=talent.power_infusion.enabled
				-- actions+=/blood_fury
				-- actions+=/berserking
				-- actions+=/arcane_torrent

				if IsSpellKnown(171146) then
					if GS.SpellCDDuration(47585, nil) == 0 then
						GS.Cast("player", 47585, false, false, false, "SpellToInterrupt")
						return
					end
					-- if dispersion then interrupt() end
				end

				if not GS.PlayerHasTalent(7, 1) and not GS.PlayerHasTalent(7, 2) then -- main
					if UnitChannelInfo("player") and ((UnitChannelInfo("player") ~= "Searing Insanity" and (GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1 or GS.PP() == 5)) or (UnitChannelInfo("player") == "Searing Insanity" and (GS.SpellCDDuration(8092, nil) <= 0.1 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= 0.1))) and GS.SpellCDDuration(61304, nil) == 0 then SpellStopCasting() end
					if GS.CDs and GS.SCA(34433, "target", true) then GS.Cast("target", 34433, false, false, false, "SpellToInterrupt") return end -- shadowfiend

					if GS.SIR(32379) and GS.PP() <= 4 then -- shadow word death
						if GS.SCA(32379, "target", true) and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, true) and GS.Health(obj, maxhealth, true) < 20 then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end

					if GS.PlayerHasGlyph(162532) and GS.SIR(8092) and GS.PP() <= 2 and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) then -- mind harvest if 2 or less shadow orbs
						if GS.SCA(8092, "target", true) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(8092, obj, true) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					
					if GS.SIR(2944) then
						if GS.PP() == 5 then -- dump, aoe if surge of darkness or four piece else single target
							if GS.AoE and (GS.PlayerHasTalent(3, 1) or GS.TierBonus("t17") >= 4) then
								local currentTarget = ObjectPointer("target")
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(2944, obj, true) and not GS.Aura(obj, 158831, "", "PLAYER") then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
								end
							end
							if GS.SCA(2944, "target", true) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- dump
						end
						if GS.SCA(2944, "target", true) and GS.PlayerHasTalent(7, 3) then -- dump before we lose shadow orbs with apparitions
							if GS.PP() >= 3 and GS.Priest.Apparitions >= 3 then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
							if GS.PP() >= 4 and GS.Priest.Apparitions >= 2 then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						end
						if GS.SCA(2944, "target", true) and GS.PP() >= 3 and GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))) and not GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*.7) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- t17 keep up
						if GS.PlayerHasTalent(7, 3) and GS.PP() >= 4 and ((GS.SpellCDDuration(8092, nil) < (1.5/(1+GetHaste()*.01)) and GS.TierBonus("t17") < 2) or (GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) < (1.5/(1+GetHaste()*.01)))) then -- shadowy apparition dump before mind blast or shadow word death
							if GS.AoE and GS.PlayerHasTalent(3, 1) then
								local currentTarget = ObjectPointer("target")
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(2944, obj, true) and obj ~= currentTarget and not GS.Aura(obj, 158831) then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
								end
							end
							if GS.SCA(2944, "target", true) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						elseif GS.PP() >= 3 and ((GS.SpellCDDuration(8092, nil) < (1.5/(1+GetHaste()*.01)) and GS.TierBonus("t17") < 2) or (GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) < (1.5/(1+GetHaste()*.01)))) then -- dump before mind blast or shadow word death
							if GS.AoE and GS.PlayerHasTalent(3, 1) then
								local currentTarget = ObjectPointer("target")
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(2944, obj, true) and obj ~= currentTarget and not GS.Aura(obj, 158831) then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
								end
							end
							if GS.SCA(2944, "target", true) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						end
					end

					if GS.PlayerHasGlyph(162532) and GS.SIR(8092) then
						if GS.SCA(8092, "target", true) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(8092, obj, true) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
							end
						end
					end

					if GS.SCA(8092, "target", true) and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return end
					if GS.Aura("player", 132573) then -- insanity buff
						-- if GS.AoE and GS.TargetCount(10) >= 3 then -- mind sear keep updated: turn this on upcoming patch 6.1
						-- 	if GS.SCA(searing_insanity, "target", true) then
						-- 		if UnitChannelInfo("player") and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) and GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= 5/(1+GetHaste()*.01)/5 then GS.Cast("target", searing_insanity, false, false, false, "Searing Insanity") return end
						-- 		if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then GS.Cast("target", searing_insanity, false, false, false, "SpellToInterrupt") return end
						-- 		if not UnitChannelInfo("player") and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then GS.Cast("target", searing_insanity, false, false, false, "SpellToInterrupt") return end
						-- 	end
						-- else -- mind flay
							if GS.SCA(129197, "target", false) then
								if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 15407, false, false, false, "Insanity") return end
								if UnitChannelInfo("player") == "Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= (3/(1+GetHaste()*.01)/4) then GS.Cast("target", 15407, false, false, false, "Insanity") return end
								if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
							end
						-- end
					end

					if GS.PlayerHasTalent(6, 3) then
						if GS.AoE and GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and #GS.PullEnemies(30, true) > 2 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
					elseif GS.PlayerHasTalent(6, 2) then
						if GS.AoE and GS.TargetCount(8) > 4 and GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
					elseif GS.PlayerHasTalent(6, 1) then
						if GS.AoE and GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 and #GS.PullEnemies(40, true) > 2 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
					end

					if (not GS.AoE or #GS.PullEnemies(40, true) <= 5) then -- dot up
						if GS.SIR(589) then
							if GS.SCA(589, "target", true) and (GS.Aura("target", 589, "", "PLAYER") or #tShadowWordPain < 5) and (not GS.Aura("target", 589, "", "PLAYER") or GS.AuraRemaining("target", 589, 5.4, "", "PLAYER")) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								if #tShadowWordPain < 5 then
									for i = 1, #tNoObjectShadowWordPain do
										local obj = tNoObjectShadowWordPain[i]
										if GS.SCA(589, obj, true) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
									end
								end
								for i = 1, #tShadowWordPain do
									local obj = tShadowWordPain[i]
									if GS.SCA(589, obj, true) and GS.AuraRemaining(obj, 589, 5.4, "", "PLAYER") then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SIR(34914) then
							if GS.SCA(34914, "target", true) and GS.Priest.VampiricTouchThrottle[UnitGUID("target")] == 0 and (GS.Aura("target", 34914, "", "PLAYER") or #tVampiricTouch < 5) and (not GS.Aura("target", 34914, "", "PLAYER") or GS.AuraRemaining("target", 34914, 4.5+(select(4, GetSpellInfo(34914))*0.001))) then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								if #tVampiricTouch < 5 then
									for i = 1, #tNoObjectVampiricTouch do
										local obj = tNoObjectVampiricTouch[i]
										if GS.SCA(34914, obj, true) and GS.Priest.VampiricTouchThrottle[UnitGUID(obj)] == 0 then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
									end
								end
								for i = 1, #tVampiricTouch do
									local obj = tVampiricTouch[i]
									if GS.SCA(34914, obj, true) and GS.Priest.VampiricTouchThrottle[UnitGUID(obj)] == 0 and GS.AuraRemaining(obj, 34914, 4.5+(select(4, GetSpellInfo(34914))*0.001)) then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
					end
					if GS.SCA(2944, "target", true) and GS.PP() >= 3 and GS.AuraRemaining("target", 158831, 1, "", "PLAYER") then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- clip devouring plague
					if GS.SCA(73510, "target", true) and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) and GS.AuraStacks("player", 87160, 3) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end -- mind spike dump surge of darkness stacks
					
					if GS.PlayerHasTalent(6, 3) and GS.Distance("target", nil) <= 30 and GS.Distance("target", nil) >= 17 and GS.SIR(120644) then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end -- halo
					if GS.PlayerHasTalent(6, 1) and GS.SIR(127632) and (GS.AoE and #GS.PullEnemies(40, true) > 1 or GS.Distance("target", nil) >= 28) and GS.Distance("target", nil) <= 40 and GS.Distance("target", nil) >= 11 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end -- cascade
					
					if GS.PlayerHasTalent(6, 2) and GS.SIR(122121) and (GS.TargetCount(8) > 1 and GS.Distance("target", nil) <= 24) then
						local rot = ObjectFacing("player")
						GS.Face("target")
						GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
						FaceDirection(rot)
						return
					end
					
					if GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) < .5 and (not GS.AoE or #GS.PullEnemies(40, true) == 1) then return end -- wait for shadow word death
					if GS.SpellCDDuration(8092, nil) < .5 and GS.SpellCDDuration(8092, nil) > 0 and (not GS.AoE and #GS.PullEnemies(40, true) == 1) then return end -- wait for mind blast
					
					if GS.SCA(73510, "target", true) and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) and GS.Aura("player", 87160) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end -- mind spike dump surge of darkness stacks
					if GS.PlayerHasTalent(6, 2) and GS.SIR(122121) and GS.Distance("target", nil) <= 28 and GS.TargetCount(8) > 1 then
						local rot = ObjectFacing("player")
						GS.Face("target")
						GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
						FaceDirection(rot)
						return
					end

					if GS.AoE and GS.SCA(48045, "target", true) and GS.TargetCount(10) >= 4 then -- mind sear
						if UnitChannelInfo("player") == "Mind Sear" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= (5/(1+GetHaste()*.01)/5) then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					end

					if GS.PP() >= 2 and GS.PlayerHasTalent(3, 3) then -- refresh dots before getting insanity up
						if GS.SCA(589, "target", true) and GS.AuraRemaining("target", 589, 9, "", "PLAYER") then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end -- shadow word pain
						if GS.SCA(34914, "target", true) and GS.Priest.VampiricTouchThrottle[UnitGUID("target")] and GS.AuraRemaining("target", 34914, 10.5, "", "PLAYER") then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return end -- vampiric touch
					end
					if GS.SCA(15407, "target", true) then -- mind flay
						if UnitChannelInfo("player") == "Mind Flay" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= (3/(1+GetHaste()*.01)/4) then GS.Cast("target", 15407, false, false, false, "Mind Flay") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end
					if IsPlayerMoving() and not GS.Aura("player", 172106) then
						if GS.SIR(32379) then -- moving shadow word death
							if GS.SCA(32379, "target", interruptCasting) then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.PlayerHasTalent(2, 1) and GS.SCA(17, "player", interruptCasting) then GS.Cast("player", 17, false, false, false, "SpellToInterrupt") return end
						
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						end

						if GS.SCA(589, "target", interruptCasting) and (not GS.Aura("target", 589, "", "PLAYER") or GS.AuraRemaining("target", 589, 5.4, "", "PLAYER")) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #tNoObjectShadowWordPain do
								local obj = tNoObjectShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
							table.sort(tShadowWordPain, function(a,b) return (select(7, GS.Aura(a, 589, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 589, "", "PLAYER"))-GetTime()) end)
							for i = 1, #tShadowWordPain do
								local obj = tShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
						if GS.SCA(589, "target", interruptCasting) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
					end
					return
				end

				if GS.PlayerHasTalent(7, 2) then -- vent
					if GS.SIR(155361) then -- void entropy
						if (not GS.AoE or #GS.PullEnemies(40, true) == 1) and GS.PP() == 3 and GS.SCA(155361, "target", interruptCasting) and not GS.Aura("target", 155361, "", "PLAYER") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] > 60 then GS.Cast("target", 155361, false, false, false, "SpellToInterrupt") return end
						if GS.AoE and #GS.PullEnemies(40, true) > 1 and GS.PP() == 5 and #tVoidEntropy < 6 then
							if GS.SCA(155361, "target", interruptCasting) and not GS.Aura("target", 155361, "", "PLAYER") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] > 60 then GS.Cast("target", 155361, false, false, false, "SpellToInterrupt") return end
							for i = 1, #tNoObjectVoidEntropy do
								local obj = tNoObjectVoidEntropy[i]
								if GS.SCA(155361, obj, interruptCasting) and not GS.Aura(obj, 155361, "", "PLAYER") and GS.TTD[obj] and GS.TTD[obj] ~= math.huge and GS.TTD[obj] > 60 then GS.Cast("target", 155361, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					
					if GS.SIR(2944) then
						if GS.SCA(2944, "target", interruptCasting) and (not GS.AoE or #GS.PullEnemies(40, true) == 1) and GS.PP() == 5 and GS.Aura("target", 155361, "", "PLAYER") and GS.AuraRemaining("target", 155361, (1.5/(1+GetHaste()*.01))*2, "", "PLAYER") then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- void entropy refresh
						if GS.AoE and #GS.PullEnemies(40,true) > 1 then -- void entropy refresh aoe
							table.sort(tVoidEntropy, function(a,b)
								if (select(7, GS.Aura(a, 155361, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 155361, "", "PLAYER"))-GetTime()) then return true else return false end
							end)
							for i = 1, #tVoidEntropy do
								if not GS.AuraRemaining(tVoidEntropy[i], 155361, (1.5/(1+GetHaste()*.01))*2) then break end
								if GS.SCA(2944, tVoidEntropy[i], interruptCasting) and GS.AuraRemaining(tVoidEntropy[i], 155361, (1.5/(1+GetHaste()*.01))*2) then GS.Cast(tVoidEntropy[i], 2944, false, false, false, "SpellToInterrupt") return end
							end
							if GS.SCA(2944, "target", interruptCasting) and GS.Aura("target", 155361, "", "PLAYER") and GS.AuraRemaining("target", 155361, (1.5/(1+GetHaste()*.01))*2, "", "PLAYER") then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						end
						if GS.PP() == 5 then
							if GS.AoE and #GS.PullEnemies(40, true) > 1 then -- refresh void entropy at different stages depending on howmany active mobs
								local remainingVoid = #GS.PullEnemies(40, true) == 2 and 5 or #GS.PullEnemies(40, true) == 3 and 10 or #GS.PullEnemies(40, true) == 4 and 15 or #GS.PullEnemies(40, true) > 4 and 20
								if GS.SCA(2944, "target", interruptCasting) and GS.AuraRemaining("target", 155361, remainingVoid) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return
								else
									for i = 1, #GS.Targets do
										local obj = GS.Targets[i]
										if GS.SCA(2944, obj, interruptCasting) and GS.AuraRemaining(obj, 155361, remainingVoid, "", "PLAYER") then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
									end
								end
							end
							if GS.SCA(2944, "target", interruptCasting) and (not GS.AoE or #GS.PullEnemies(40, true) == 1) and GS.Aura("target", 155361, "", "PLAYER") and (GS.SpellCDDuration(8092, nil) <= (1.5/(1+GetHaste()*.01))*2 or (ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= (1.5/(1+GetHaste()*.01))*2)) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- mind blast or shadow word death in the next two gcds dump orbs
							if GS.AoE and #GS.PullEnemies(40, true) > 1 and (GS.SpellCDDuration(8092, nil) <= (1.5/(1+GetHaste()*.01))*2 or (ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= (1.5/(1+GetHaste()*.01))*2)) then -- mind blast or shadow word death in the next two gcds hit lowest void entropy
								table.sort(tVoidEntropy, function(a,b)
									if (select(7, GS.Aura(a, 155361, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 155361, "", "PLAYER"))-GetTime()) then return true else return false end
								end)
								for i = 1, #tVoidEntropy do
									if GS.SCA(2944, tVoidEntropy[i], interruptCasting) then GS.Cast(tVoidEntropy[i], 2944, false, false, false, "SpellToInterrupt") return end
								end
								if GS.SCA(2944, "target", interruptCasting) and GS.Aura("target", 155361, "", "PLAYER") then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
							end
						end
						if GS.SCA(2944, "target", interruptCasting) and GS.PP() >= 3 and GS.Aura("target", 155361, "", "PLAYER") and (not GS.AoE or #GS.PullEnemies(40, true) == 1) and GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*1.4) and not GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*.7) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
					end

					if GS.SCA(34433, "target", interruptCasting) and GS.SpellCDDuration(8092, nil) >= (1.5/(1+GetHaste()*.01)) then GS.Cast("target", 34433, false, false, false, "SpellToInterrupt") return end -- shadowfiend
					if GS.AoE and GS.PlayerHasTalent(6, 3) and GS.SIR(120644) and GS.Distance("target", nil) <= 30 and GS.PlayerCount(30) >= 4 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end -- halo aoe
					if GS.PlayerHasGlyph(162532) and GS.SIR(8092) and GS.PP() <= 2 and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) then -- mind harvest if 2 or less shadow orbs
						if GS.SCA(8092, "target", interruptCasting) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(8092, obj, interruptCasting) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					
					if GS.PlayerHasGlyph(162532) and GS.SIR(2944) and GS.PP() >= 3 then -- dump devouring plague before supah mind blast
						if GS.AoE then
							for i = 1, #GS.Targets do
								if GS.Priest.MindHarvest[UnitGUID(GS.Targets[i])] == 0 then
									GS.Cast("target", 2944, false, false, false, "SpellToInterrupt")
									return
								end
							end
						else
							if GS.SCA(2944, "target", interruptCasting) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						end
					end
					
					if GS.SCA(8092, "target", interruptCasting) and GS.PP() <= 4 and (not GS.AoE or #GS.PullEnemies(40, true) <= 10) then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return end
					if GS.SIR(32379) and GS.PP() <= 4 then -- shadow word death
						if GS.SCA(32379, "target", interruptCasting) and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					-- if GS.Aura("player", 132573) and GS.TargetCount(10) >= 3 and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then -- searing insanity -- keep updated: turn this on patch 6.1
					-- 	if GS.SCA(48045, "target", interruptCasting) and GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- insanity is running out
					-- 	if GS.SCA(48045, "target", interruptCasting) and UnitChannelInfo("player") == "Searing Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- chain the spell
					-- 	if GS.SCA(48045, "target", interruptCasting) and not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- end
					if GS.SCA(589, "target", interruptCasting) and GS.TierBonus("t17") >= 2 and GS.PP() == 4 and GS.AuraRemaining("target", 589, 9, "", "PLAYER") and GS.SpellCDDuration(8092, nil) < 1.2*(1.5/(1+GetHaste()*.01)) and GS.SpellCDDuration(8092, nil) > .2*(1.5/(1+GetHaste()*.01)) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end -- shadow word pain tier bonus refresh so we won't have to insanity
					if GS.Aura("player", 132573) and GS.SCA(129197, "target", interruptCasting) and GS.TargetCount(10) <= 3 and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then -- insanity
						if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end -- insanity is running out
						if UnitChannelInfo("player") == "Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end -- chain the spell
						if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SCA(73510, "target", interruptCasting) and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) and GS.AuraStacks("player", 87160, 3) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end -- mind spike dump surge of darkness stacks
					if GS.SIR(589) then
						if GS.SCA(589, "target", interruptCasting) and (GS.Aura("target", 589, "", "PLAYER") or #tShadowWordPain < 5) and GS.AuraRemaining("target", 589, 6.3, "", "PLAYER") then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							if #tShadowWordPain < 5 then
								for i = 1, #tNoObjectShadowWordPain do
									local obj = tNoObjectShadowWordPain[i]
									if GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
								end
							end
							for i = 1, #tShadowWordPain do
								local obj = tShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) and GS.AuraRemaining(obj, 589, 6.3, "", "PLAYER") then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SIR(34914) then
						if GS.SCA(34914, "target", interruptCasting) and (GS.Aura("target", 34914, "", "PLAYER") or #tVampiricTouch < 5) and GS.AuraRemaining("target", 34914, 5.25, "", "PLAYER") then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							if #tVampiricTouch < 5 then
								for i = 1, #tNoObjectVampiricTouch do
									local obj = tNoObjectVampiricTouch[i]
									if GS.SCA(34914, obj, interruptCasting) then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
								end
							end
							for i = 1, #tVampiricTouch do
								local obj = tVampiricTouch[i]
								if GS.SCA(34914, obj, interruptCasting) and GS.AuraRemaining(obj, 34914, 5.25, "", "PLAYER") then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil) <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil) <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.TargetCount(8) > 4 and GS.Distance("target", nil) <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						end
					
						if GS.SCA(73510, "target", interruptCasting) and (not GS.AoE or #GS.PullEnemies(40, true) <= 5) and GS.Aura("player", 87160) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end -- mind spike dump surge of darkness stacks

						if GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 3 then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end

						if GS.SCA(15407, "target", interruptCasting) and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindFlay then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(15407, "target", interruptCasting) and not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end
					if IsPlayerMoving() and not GS.Aura("player", 172106) then
						if GS.SIR(32379) then -- moving shadow word death
							if GS.SCA(32379, "target", interruptCasting) then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.PlayerHasTalent(2, 1) and GS.SCA(17, "player", interruptCasting) then GS.Cast("player", 17, false, false, false, "SpellToInterrupt") return end
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						end
						if GS.SCA(589, "target", interruptCasting) and (not GS.Aura("target", 589, "", "PLAYER") or GS.AuraRemaining("target", 589, 5.4, "", "PLAYER")) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #tNoObjectShadowWordPain do
								local obj = tNoObjectShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
							table.sort(tShadowWordPain, function(a,b) return (select(7, GS.Aura(a, 589, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 589, "", "PLAYER"))-GetTime()) end)
							for i = 1, #tShadowWordPain do
								local obj = tShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
						if GS.SCA(589, "target", interruptCasting) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
					end
					return
				end

				if GS.PlayerHasTalent(7, 1) and not GS.PlayerHasTalent(3, 3) then -- cop
					if GS.SIR(2944, "target", interruptCasting) then -- devouring plague
						if GS.PP() == 5 then -- dump shadow orbs
							if GS.AoE then
								local currentTarget = ObjectPointer("target")
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if obj ~= currentTarget and not GS.Aura(obj, 158831, "", "PLAYER") and GS.TTD[obj] and GS.TTD[obj] ~= math.huge and GS.TTD[obj] >= (1.5/(1+GetHaste()*.01))*4*7/6 then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
								end
							end
							if GS.SCA(2944, "target", interruptCasting) and not GS.Aura("target", 158831, "", "PLAYER") then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- no devouring plague already
							if (GS.SpellCDDuration(8092, nil) <= (1.5/(1+GetHaste()*.01)) or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= (1.5/(1+GetHaste()*.01))) then
								if GS.AoE then
									local currentTarget = ObjectPointer("target")
									for i = 1, #GS.Targets do
										local obj = GS.Targets[i]
										if obj ~= currentTarget and GS.TTD[obj] and GS.TTD[obj] ~= math.huge and GS.TTD[obj] >= (1.5/(1+GetHaste()*.01))*4*7/6 then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
									end
								end
								if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- mind blast or shadow word: death is about to come up
							end
						end

						if GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))) and not GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*.7) then
							if GS.AoE then -- cast on anything but target first
								local currentTarget = ObjectPointer("target")
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if obj ~= currentTarget and GS.SCA(2944, obj, interruptCasting) then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
								end
							end
							if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end
						end
						if GS.TierBonus("t17") < 4 and GS.PP() >= 3 then -- fall back
							if GS.TierBonus("t17") < 2 and (GS.SpellCDDuration(8092, nil) <= (1.5/(1+GetHaste()*.01)) or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= (1.5/(1+GetHaste()*.01))) then
								if GS.AoE then -- cast on anything but target first
									local currentTarget = ObjectPointer("target")
									for i = 1, #GS.Targets do
										local obj = GS.Targets[i]
										if GS.SCA(2944, obj, interruptCasting) and obj ~= currentTarget and GS.TTD[obj] and GS.TTD[obj] ~= math.huge and GS.TTD[obj] >= ((1.5/(1+GetHaste()*.01))*4*7/6) then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
									end
								end
								if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- cast on target if nothing else is valid
							elseif (GS.SpellCDDuration(8092, nil) <= 2 or GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) <= (1.5/(1+GetHaste()*.01))) then
								if GS.AoE then -- cast on anything but target first
									local currentTarget = ObjectPointer("target")
									for i = 1, #GS.Targets do
										local obj = GS.Targets[i]
										if GS.SCA(2944, obj, interruptCasting) and obj ~= currentTarget and GS.TTD[obj] and GS.TTD[obj] ~= math.huge and GS.TTD[obj] >= ((1.5/(1+GetHaste()*.01))*4*7/6) then GS.Cast(obj, 2944, false, false, false, "SpellToInterrupt") return end
									end
								end
								if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- cast on target if nothing else is valid
							end
						end
					end

					if GS.SCA(8092, "target", interruptCasting) and GS.PlayerHasGlyph(162532) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
					elseif GS.AoE and GS.PlayerHasGlyph(162532) then
						for i = 1, #GS.Targets do
							local obj = GS.Targets[i]
							if GS.SCA(8092, "target", interruptCasting) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(8092, "target", interruptCasting) and #GS.PullEnemies(40, true) <= 5 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return end -- mind blast ifthere's less than 5 targets
					if GS.SIR(32379) then -- shadow word death non DoTs
						if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SIR(32379) then -- shadow word death dots or not
						if GS.SCA(32379, "target", interruptCasting) and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					
					-- if GS.Aura("player", 132573) and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 3 and GS.SpellCDDuration(8092, nil) > 0.5*(1.5/(1+GetHaste()*.01)) then -- keep updated: turn on searing insanity before 6.1
					-- 	if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- insanity is running out
					-- 	if UnitChannelInfo("player") == "Searing Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- chain the spell
					-- 	if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- end

					if GS.SCA(34433, "target", interruptCasting) then GS.Cast("target", 34433, false, false, false, "SpellToInterrupt") return end -- shadowfiend
					if GS.PlayerHasTalent(6, 3) then
						if GS.SIR(120644) and GS.Distance("target", nil) <= 30 and GS.Distance("target", nil) >= 17 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
					elseif GS.PlayerHasTalent(6, 1) then
						if GS.SIR(127632) and (GS.AoE and #GS.PullEnemies(40, true) > 1 or GS.Distance("target", nil) >= 28) and GS.Distance("target", nil) <= 40 and GS.Distance("target", nil) >= 11 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
					elseif GS.PlayerHasTalent(6, 2) then
						if GS.SIR(122121) and GS.TargetCount(8) > 3 and GS.Distance("target", nil) <= 24 then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
					end
					
					if GS.AoE and #GS.PullEnemies(40, true) <= 5 then
						local currentTarget = ObjectPointer("target")
						if GS.SIR(589) then
							if #tShadowWordPain < 5 then
								for i = 1, #tNoObjectShadowWordPain do
									local obj = tNoObjectShadowWordPain[i]
									if obj ~= currentTarget and GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SIR(34914) then
							if #tVampiricTouch < 5 then
								for i = 1, #tNoObjectVampiricTouch do
									local obj = tNoObjectVampiricTouch[i]
									if obj ~= currentTarget and GS.SCA(34914, obj, interruptCasting) then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
					end

					if GS.PlayerHasTalent(6, 2) then
						if GS.SIR(122121) and GS.TargetCount(8) == 3 and GS.Distance("target", nil) <= 24 then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
					end

					if GS.AoE and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 5 then
						if UnitChannelInfo("player") == "Mind Sear" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					end

					if GS.SCA(73510, "target", interruptCasting) and (not GS.AoE or #GS.PullEnemies(40, true) <= 4) and GS.Aura("player", 87160) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end -- mind spike dump surge of darkness stacks
					
					if GS.AoE and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 3 then
						if UnitChannelInfo("player") == "Mind Sear" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SCA(15407, "target", interruptCasting) and (GS.TargetCount(10) == 1 or not GS.AoE) and not GS.AuraRemaining("target", 158831, GS.Priest.DevouringPlague, "", "PLAYER") then
						if UnitChannelInfo("player") == "Mind Flay" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindFlay then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SCA(73510, "target", interruptCasting) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end
					if IsPlayerMoving() and not GS.Aura("player", 172106) then
						if GS.SIR(32379) then -- moving shadow word death non dots
							if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SIR(32379) then -- moving shadow word death dots or not
							if GS.SCA(32379, "target", interruptCasting) then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.PlayerHasTalent(2, 1) and GS.SCA(17, "player", interruptCasting) then GS.Cast("player", 17, false, false, false, "SpellToInterrupt") return end
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						end
						if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- devouring plague moving
					end
					return
				end

				if GS.PlayerHasTalent(7, 1) and GS.PlayerHasTalent(3, 3) and GS.Health("target", false, true) > 20 and #GS.PullEnemies(40, true) <= 5 then -- cop_dotweave
					if GS.SCA(2944, "target", interruptCasting) then -- devouring plague
						if (GS.Aura("target", 34914, "", "PLAYER") and GS.Aura("target", 589, "", "PLAYER") and GS.PP() == 5) or -- if other dots are up and five shadow orbs
						(GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))) and not GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*.7)) or -- t17 4 piece
						(GS.Aura("target", 34914, "", "PLAYER") and GS.Aura("target", 589, "", "PLAYER") and not GS.Aura("player", 132573) and GS.SpellCDDuration(8092, nil) > (1.5/(1+GetHaste()*.01))*.4) then -- for insanity buff if mind blast won't be up soon
							GS.Cast("target", 2944, false, false, false, "SpellToInterrupt")
							return
						end
					end
					-- shadow word death non dots
						if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					-- shadow word death dots or not
						if GS.SCA(32379, "target", interruptCasting) and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					if GS.SIR(8092) then
						if GS.PlayerHasGlyph(162532) and GS.PP() <= 2 then
							if GS.SCA(8092, "target", interruptCasting) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(8092, obj, interruptCasting) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SCA(8092, "target", interruptCasting) and GS.PP() <= 4 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return end
					end
					-- if GS.Aura("player", 132573) and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) > 2 then -- keep updated: turn on patch 6.1
					-- 	if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- insanity is running out
					-- 	if UnitChannelInfo("player") == "Searing Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end -- chain the spell
					-- 	if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- end
					if GS.SCA(34433, "target", interruptCasting) and not GS.Aura("player", 132573) then GS.Cast("target", 34433, false, false, false, "SpellToInterrupt") return end -- shadowfiend
					if GS.PP() == 4 and GS.TierBonus("t17") >= 2 and not GS.Aura("target", 589, "", "PLAYER") and not GS.Aura("target", 158831, "", "PLAYER") and GS.SpellCDDuration(8092, nil) < 1.2*(1.5/(1+GetHaste()*.01)) and GS.SpellCDDuration(8092, nil) > .2*(1.5/(1+GetHaste()*.01)) then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
					if GS.PP() == 5 then
						if GS.SCA(589, "target", interruptCasting) and not GS.Aura("target", 589, "", "PLAYER") and not GS.Aura("target", 158831, "", "PLAYER") then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(34914, "target", interruptCasting) and GS.Priest.VampiricTouchThrottle[UnitGUID("target")] == 0 and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 158831, "", "PLAYER") then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return end
					end
					
					if GS.Aura("player", 132573) and GS.SCA(129197, "target", interruptCasting) then
						if UnitChannelInfo("player") == "Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindFlay then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end

					if GS.PP() >= 2 and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) and GS.Bloodlust() and GS.TierBonus("t17") < 2 then -- refresh dots under bloodlust and before devouring plague
						if GS.SCA(589, "target", interruptCasting) and not GS.AuraRemaining("target", 589, 6, "", "PLAYER") and GS.Aura("target", 34914, "", "PLAYER") then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(34914, "target", interruptCasting) and not GS.AuraRemaining("target", 34914, 5, "", "PLAYER") then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return end
					end

					if GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil) <= 30 and GS.Distance("target", nil) >= 17 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and (GS.AoE and #GS.PullEnemies(40, true) > 1 or GS.Distance("target", nil) >= 28) and GS.Distance("target", nil) <= 40 and GS.Distance("target", nil) >= 11 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.TargetCount(8) > 3 and GS.Distance("target", nil) <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						end
					end
					if GS.AoE then
						local currentTarget = ObjectPointer("target")
						if #tShadowWordPain < 5 then
							for i = 1, #tNoObjectShadowWordPain do
								local obj = tNoObjectShadowWordPain[i]
								if GS.SCA(589, obj, interruptCasting) and currentTarget ~= obj then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
						if #tVampiricTouch < 5 then
							for i = 1, #tNoObjectVampiricTouch do
								local obj = tNoObjectVampiricTouch[i]
								if GS.SCA(34914, obj, interruptCasting) and currentTarget ~= obj then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.PlayerHasTalent(6, 2) and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then
						if GS.SIR(122121) and GS.TargetCount(8) == 3 and GS.Distance("target", nil) <= 24 then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
					end
					if GS.AoE then
						local currentTarget = ObjectPointer("target")
						for i = 1, #tShadowWordPain do
							local obj = tShadowWordPain[i]
							if GS.SCA(589, "target", interruptCasting) and currentTarget ~= obj and GS.AuraRemaining(obj, 589, 5.4, "", "PLAYER") then GS.Cast("target", 589, false, false, false, "SpellToInterrupt") return end
						end
						for i = 1, #tVampiricTouch do
							local obj = tVampiricTouch[i]
							if GS.SCA(34914, "target", interruptCasting) and currentTarget ~= obj and GS.AuraRemaining(obj, 34914, 4.5, "", "PLAYER") then GS.Cast("target", 34914, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(73510, "target", interruptCasting) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end
					if IsPlayerMoving() and not GS.Aura("player", 172106) then
						if GS.SIR(32379) then -- moving shadow word death non dots
							if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SIR(32379) then -- moving shadow word death dots or not
							if GS.SCA(32379, "target", interruptCasting) then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.PlayerHasTalent(2, 1) and GS.SCA(17, "player", interruptCasting) then GS.Cast("player", 17, false, false, false, "SpellToInterrupt") return end
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						end
						if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- devouring plague moving
						if GS.AoE then
							local currentTarget = ObjectPointer("target")
							for i = 1, #tNoObjectShadowWordPain do
								local obj = tNoObjectShadowWordPain[i]
								if obj ~= currentTarget and GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
							table.sort(tShadowWordPain, function(a,b) return (select(7, GS.Aura(a, 589, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 589, "", "PLAYER"))-GetTime()) end)
							for i = 1, #tShadowWordPain do
								local obj = tShadowWordPain[i]
								if obj ~= currentTarget and GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					return
				end

				if GS.PlayerHasTalent(7, 1) and GS.PlayerHasTalent(3, 3) and GS.Health("target", false, true) <= 20 then -- cop_mfi
					if GS.SCA(2944, "target", interruptCasting) and (GS.PP() == 5 or GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*1.7) and not GS.AuraRemaining("player", 167254, (1.5/(1+GetHaste()*.01))*.7)) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- devouring plague t17 4 piece or five shadow orbs
					if GS.SIR(8092) then
						if GS.SCA(8092, "target", interruptCasting) and GS.PlayerHasGlyph(162532) and GS.Priest.MindHarvest[UnitGUID("target")] == 0 then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE and GS.PlayerHasGlyph(162532) then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(8092, obj, interruptCasting) and GS.Priest.MindHarvest[UnitGUID(obj)] == 0 then GS.Cast(obj, 8092, false, false, false, "SpellToInterrupt") return end
							end
						end
						if GS.SCA(8092, "target", interruptCasting) and (#GS.PullEnemies(40, true) <= 5 or not GS.AoE) then GS.Cast("target", 8092, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SIR(32379) then -- shadow word death non dots
						if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SIR(32379) then -- shadow word death dots or not
						if GS.SCA(32379, "target", interruptCasting) and GS.Health("target", maxhealth, true) < 20 then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(32379, obj, interruptCasting) and GS.Health(obj, maxhealth, true) < 20 then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SCA(2944, "target", interruptCasting) and GS.PP() >= 3 and GS.TierBonus("t17") < 4 and ((GS.TierBonus("t17") < 2 and GS.SpellCDDuration(8092, nil) < (1.5/(1+GetHaste()*.01))) or (GS.TierBonus("t17") >= 2 and GS.SpellCDDuration(8092, nil) <= 2) or (GS.ShadowWordDeath() and GS.SpellCDDuration(32379, nil) < (1.5/(1+GetHaste()*.01)))) then
						GS.Cast("target", 2944, false, false, false, "SpellToInterrupt")
						return
					end
					
					-- if GS.AoE and GS.Aura("player", 132573) and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 3 and GS.SpellCDDuration(8092, nil) > .5*(1.5/(1+GetHaste()*.01)) then -- keep updated: turn on patch 6.1
					-- 	if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- 	if UnitChannelInfo("player") == "Searing Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- 	if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					-- end
					
					if GS.SCA(34433, "target", interruptCasting) then GS.Cast("target", 34433, false, false, false, "SpellToInterrupt") return end -- shadowfiend
					if GS.AoE and #GS.PullEnemies(40, true) <= 5 then
						local currentTarget = ObjectPointer("target")
						if GS.SIR(589) then
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(589, obj, interruptCasting) and currentTarget ~= obj and GS.AuraRemaining(obj, 589, 5.4, "", "PLAYER") then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
						if GS.SIR(34914) then
							local castTime = (select(4, GetSpellInfo(34914))*0.001)
							for i = 1, #GS.Targets do
								local obj = GS.Targets[i]
								if GS.SCA(34914, obj, interruptCasting) and currentTarget ~= obj and GS.AuraRemaining(obj, 34914, 4.5+castTime, "", "PLAYER") then GS.Cast(obj, 34914, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					
					if GS.Aura("player", 132573) and GS.SCA(129197, "target", interruptCasting) and (not GS.AoE or GS.TargetCount(10) <= 2) then
						if GS.AuraRemaining("player", 132573, .5*(1.5/(1+GetHaste()*.01))) then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
						if UnitChannelInfo("player") == "Insanity" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindFlay then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 15407, false, false, false, "SpellToInterrupt") return end
					end
					if GS.PlayerHasTalent(6, 3) then
						if GS.SIR(120644) and GS.Distance("target", nil) <= 30 and GS.Distance("target", nil) >= 17 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
					elseif GS.PlayerHasTalent(6, 1) then
						if GS.SIR(127632) and (GS.AoE and #GS.PullEnemies(40, true) > 1 or GS.Distance("target", nil) >= 28) and GS.Distance("target", nil) <= 40 and GS.Distance("target", nil) >= 11 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
					elseif GS.PlayerHasTalent(6, 2) then
						if GS.SIR(122121) and GS.TargetCount(8) > 2 and GS.Distance("target", nil) <= 24 then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
					end
					if GS.AoE and GS.SCA(48045, "target", interruptCasting) and GS.TargetCount(10) >= 6 then
						if UnitChannelInfo("player") == "Mind Sear" and (select(6, UnitChannelInfo("player"))/1000-GetTime()) <= GS.Priest.MindSear then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
						if not UnitChannelInfo("player") then GS.Cast("target", 48045, false, false, false, "SpellToInterrupt") return end
					end
					if GS.SCA(73510, "target", interruptCasting) then GS.Cast("target", 73510, false, false, false, "SpellToInterrupt") return end
					if IsPlayerMoving() and not GS.Aura("player", 172106) then
						if GS.SIR(32379) then -- moving shadow word death non dots
							if GS.SCA(32379, "target", interruptCasting) and not GS.Aura("target", 34914, "", "PLAYER") and not GS.Aura("target", 589, "", "PLAYER") then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) and not GS.Aura(obj, 34914, "", "PLAYER") and not GS.Aura(obj, 589, "", "PLAYER") then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SIR(32379) then -- moving shadow word death dots or not
							if GS.SCA(32379, "target", interruptCasting) then GS.Cast("target", 32379, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #GS.Targets do
									local obj = GS.Targets[i]
									if GS.SCA(32379, obj, interruptCasting) then GS.Cast(obj, 32379, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.PlayerHasTalent(2, 1) and GS.SCA(17, "player", interruptCasting) then GS.Cast("player", 17, false, false, false, "SpellToInterrupt") return end
						if GS.PlayerHasTalent(6, 3) then
							if GS.SIR(120644) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 then GS.Cast("target", 120644, false, false, false, "SpellToInterrupt") return end
						elseif GS.PlayerHasTalent(6, 2) then
							if GS.SIR(122121) and GS.Distance("target", nil)-UnitCombatReach("target") <= 24 then
								local rot = ObjectFacing("player")
								GS.Face("target")
								GS.Cast("target", 122121, false, false, false, "SpellToInterrupt")
								FaceDirection(rot)
								return
							end
						elseif GS.PlayerHasTalent(6, 1) then
							if GS.SIR(127632) and GS.Distance("target", nil)-UnitCombatReach("target") <= 40 then GS.Cast("target", 127632, false, false, false, "SpellToInterrupt") return end
						end
						if GS.SCA(2944, "target", interruptCasting) then GS.Cast("target", 2944, false, false, false, "SpellToInterrupt") return end -- devouring plague moving
						if GS.AoE then
							local currentTarget = ObjectPointer("target")
							for i = 1, #tNoObjectShadowWordPain do
								local obj = tNoObjectShadowWordPain[i]
								if obj ~= currentTarget and GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
							table.sort(tShadowWordPain, function(a,b) return (select(7, GS.Aura(a, 589, "", "PLAYER"))-GetTime()) < (select(7, GS.Aura(b, 589, "", "PLAYER"))-GetTime()) end)
							for i = 1, #tShadowWordPain do
								local obj = tShadowWordPain[i]
								if obj ~= currentTarget and GS.SCA(589, obj, interruptCasting) then GS.Cast(obj, 589, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					return
				end
			end
		end
	end

	function GS.DEATHKNIGHT1() -- blood
		if GetShapeshiftForm() ~= 1 then CastShapeshiftForm(1) return end
		if not IsMounted() and not GS.Aura("player", 57330) then GS.Cast(nil, 57330, nil) return end -- horn of winter
		if not GS.Combat() and not IsMounted() and GS.SIR(49222) and not GS.Aura("player", 49222) then GS.Cast(nil, 49222, nil) return end -- bone shield

		if GetMacroInfo("___GSDKCDs") then
			for i = 1, 9 do
				if i == 1 then
					if GS.PlayerHasTalent(2, 1) and GS.SIR(49039) then
						EditMacro(121, nil, nil, "#showtooltip Lichborne\n/run GS.DEATHKNIGHT1CDs()")
						break
					end -- lichborne leech 10%
				elseif i == 2 then
					if GS.SIR(42650) and not GS.Aura("player", 49222) and not GS.Aura("player", 81256) and not GS.Aura("player", 48792) and not GS.Aura("player", 55233) then EditMacro(121, nil, nil, "#showtooltip Army of the Dead\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end  -- army of the dead
				elseif i == 3 then
					if GS.SIR(49222) and not GS.Aura("player", 42650) and not GS.Aura("player", 49222) and not GS.Aura("player", 81256) and not GS.Aura("player", 48792) and not GS.Aura("player", 55233) then EditMacro(121, nil, nil, "#showtooltip Bone Shield\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end -- bone shield
				elseif i == 4 then
					if GS.SIR(55233) and GS.Health("player", nil, true) < 50 then EditMacro(121, nil, nil, "#showtooltip Vampiric Blood\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end -- vampiric blood
				elseif i == 5 then
					if GS.SIR(48792) and GS.Health("player", nil, true) < 30 and not GS.Aura("player", 42650) and not GS.Aura("player", 81256) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) then EditMacro(121, nil, nil, "#showtooltip Icebound Fortitude\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end -- icebound fortitude
				elseif i == 6 then
					if GS.SIR(48982) and GS.Health("player", nil, true) < 50 and not GS.Aura("player", 42650) and not GS.Aura("player", 81256) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) and not GS.Aura("player", 48792) then EditMacro(121, nil, nil, "#showtooltip Rune Tap\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end --  rune tap
				elseif i == 7 then
					if GS.SIR(49028) and GS.Health("player", nil, true) < 80 and not GS.Aura("player", 42650) and not GS.Aura("player", 48792) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) then EditMacro(121, nil, nil, "#showtooltip Dancing Rune Weapon\n/run GS.DEATHKNIGHT1CDs()") 
					break
					end -- dancing rune weapon
				elseif i == 8 then
					if GS.PlayerHasTalent(5, 1) and GS.Health("player", nil, true) < 50 and GS.SIR(48743) then EditMacro(121, nil, nil, "#showtooltip Death Pact\n/run GS.DEATHKNIGHT1CDs()")
					break
					end -- death pact
				elseif i == 9 then
					EditMacro(121, nil, nil, "/run GS.DEATHKNIGHT1CDs()")
				end
			end
		end

		if GS.Combat() then
			local blood, frost, unholy, death = GS.RuneCheck("slot")

			if GS.ValidTarget() then
				StartAttack("target")
				if GS.SCA(49998) and GS.DeathStrike then
					GS.Cast(nil, 49998)
					-- GS.DeathStrike = false
					return
				end -- death siphon

				if GS.CDs and GS.SIR(20572) and GSR.Race == "Orc" and GS.UnitIsBoss("target") then GS.Cast(nil, 20572, nil) return end -- bloodfury
				if GS.CDs and GS.SIR(26297) and GSR.Race == "Troll" and GS.UnitIsBoss("target") then GS.Cast(nil, 26297, nil) return end -- berserking
				if GS.CDs and GS.SIR(50613) and GSR.Race == "BloodElf" and GS.UnitIsBoss("target") then GS.Cast(nil, 50613, nil) return end -- arcane torrent

				-- if GS.SCA(49998) and incoming_damage_5s >= GS.Health("player", true, false)*0.65 then GS.Cast(nil, 49998, nil) return end -- death strike
				-- actions+=/death_strike,if=incoming_damage_5s>=health.max*0.65
				if GS.SIR(77575) and not GS.Aura("player", 115989) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and ((GS.Aura("target", 55078, "", "PLAYER") and GS.AuraRemaining("target", 55078, 8, "", "PLAYER")) or (GS.Aura("target", 55095, "", "PLAYER") and GS.AuraRemaining("target", 55095, 8, "", "PLAYER"))))) then GS.Cast(nil, 77575, nil) return end -- outbreak
				if GS.SCA(47541) and GS.PP() > 90 then GS.Cast(nil, 47541, nil)	 return end -- death coil
				if not GS.DeathStrike and GS.SCA(45462) and ((not GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 55078, "", "PLAYER")) or (GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER"))) then GS.Cast(nil, 45462, nil) return end -- plague strike
				if not GS.DeathStrike and GS.SCA(45477) and ((not GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 55095, "", "PLAYER")) or (GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER"))) then GS.Cast(nil, 45477, nil) return end -- icy touch
				if not GS.DeathStrike and GS.PlayerHasTalent(7, 2) and GS.SIR(152280) then GS.Cast(nil, 152280, GS.SmartAoE(30, 8, true)) return end -- defile

				if GS.PlayerHasTalent(1, 2) and ((blood == 0 and unholy == 0) or (blood == 0 and frost == 0) or (unholy == 0 and frost == 0)) and GS.SCA(123693, "target", interruptCasting) and GS.SpellCDDuration(77575, nil) <= 1 and (GS.Aura("target", 155159, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER") and GS.Aura("target", 55095, "", "PLAYER")) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech
				if GS.PlayerHasTalent(4, 1) then -- blood tap rotation
					if GS.SCA(49998) and (unholy == 2 or frost == 2) then GS.Cast(nil, 49998, nil) return end -- death strike
					if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and blood == 0 then GS.Cast(nil, 45529, nil) return end -- blood tap
					if GS.SCA(49998, "target", interruptCasting) and unholy > 0 and frost > 0 and GS.AuraStacks("player", 114851, 10) then GS.Cast("target", 49998, false, false, false, "SpellToInterrupt") return end -- death strike dump blood tap
					if GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) then
						if GS.AuraStacks("player", 114851, 10) and unholy == 0 and frost == 0 then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap dump unholy and frost
						if unholy == 0 or frost == 0 then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blodo tamp dump unholy or frost
						if GS.RuneCheck("onlyDeath", "Blood") > 0 and unholy == 0 and frost == 0 then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap bloods are death runes and no unholy frost
					end
					if GS.SCA(47541) and GS.PP() > 70 then GS.Cast(nil, 47541, nil) return end -- death coil
					if GS.TTD[ObjectPointer("target")] and GS.SCA(114866) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 and (blood == 2 or blood > 0 and GS.RuneCheck("onlyDeath", "Blood") == 0) then GS.Cast(nil, 114866, nil) return end -- soul reaper
					if GS.SIR(50842) and GS.PlayerCount(10) > 0 and (blood == 2 or blood > 0 and GS.RuneCheck("onlyDeath", "Blood") == 0) then GS.Cast(nil, 50842, nil) return end -- blood boil
				elseif GS.PlayerHasTalent(4, 2) then -- runic empowerement rotation
					if GS.SCA(49998, "target", interruptCasting) and unholy > 0 and frost > 0 then GS.Cast("target", 49998, false, false, false, "SpellToInterrupt") return end -- death strike
					if GS.SCA(47541) and GS.PP() > 70 then GS.Cast(nil, 47541, nil) return end -- death coil
					if GS.TTD[ObjectPointer("target")] and GS.SCA(114866) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 and (blood == 2) then GS.Cast(nil, 114866, nil) return end -- soul reaper
					if GS.SIR(50842) and GS.PlayerCount(10) > 0 and blood == 2 then GS.Cast(nil, 50842, nil) return end -- blood boil
				elseif GS.PlayerHasTalent(4, 3) then -- runic corruption rotation
					if GS.SCA(49998) and (unholy == 2 or frost == 2) then GS.Cast(nil, 49998, nil) return end -- death strike
					if GS.SCA(47541) and GS.PP() > 70 then GS.Cast(nil, 47541, nil) return end -- death coil
					if GS.TTD[ObjectPointer("target")] and GS.SCA(114866) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 and (blood >= 1) then GS.Cast(nil, 114866, nil) return end -- soul reaper
					if GS.SIR(50842) and GS.PlayerCount(10) > 0 and blood == 2 then GS.Cast(nil, 50842, nil) return end -- blood boil
				else -- why the fuck would you have no talent?
					if GS.SCA(49998) and (unholy == 2 or frost == 2) then GS.Cast(nil, 49998, nil) return end -- death strike
					if GS.SCA(47541) and GS.PP() > 70 then GS.Cast(nil, 47541, nil) return end -- death coil
					if GS.TTD[ObjectPointer("target")] and GS.SCA(114866) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 and (blood >= 1) then GS.Cast(nil, 114866, nil) return end -- soul reaper
					if GS.SIR(50842) and GS.PlayerCount(10) > 0 and blood >= 1 then GS.Cast(nil, 50842, nil) return end -- blood boil
				end
				if GS.SIR(43265) and GS.Aura("player", 81141) then GS.Cast(nil, 43265, GS.SmartAoE(30, 8, true)) return end -- free death and decay
				if GS.SIR(50842) and GS.PlayerCount(10) > 0 and GS.Aura("player", 81141) then GS.Cast("target", 50842, false, false, false, "SpellToInterrupt") return end -- free blood boil
				
				if GS.TTD[ObjectPointer("target")] and GS.SCA(114866) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 and blood >= 1 then GS.Cast(nil, 114866, nil) return end -- soul reaper
				if GS.SIR(50842) and GS.PlayerCount(10) > 0 and blood == 2 then GS.Cast(nil, 50842, nil) return end -- blood boil
				if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and (blood == 0 or frost == 0 or unholy == 0) then GS.Cast(nil, 45529, nil) return end -- blood tap
				

				if GS.SCA(47541) then GS.Cast(nil, 47541, nil) return end -- death coil
				if GS.SIR(47568) and blood == 0 and unholy == 0 and frost == 0 then GS.Cast(nil, 47568, nil) return end -- empower rune weapon
			end
		end
	end

	function GS.DEATHKNIGHT2() -- frost todo: implement
			if GetShapeshiftForm() ~= 2 then CastShapeshiftForm(2) return end
			if not GS.Combat() and GS.SIR(57330) and not IsMounted() and not GetRaidBuffTrayAuraInfo(3) then GS.Cast("player", 57330, nil) return end -- horn of winter
			if GS.Combat() then
				local blood, frost, unholy = GS.RuneCheck("slot")
				local _, _, _, death = GS.Runes()
				if GS.ValidTarget() then
					StartAttack("target")

					if GS.CDs and GS.SIR(51271) then GS.Cast("target", 51271, false, false, false, "SpellToInterrupt") return end -- pillar of frost
					-- actions+=/potion,name=draenic_strength,if=target.time_to_die<=30|(target.time_to_die<=60&buff.pillar_of_frost.up)
					-- actions+=/empower_rune_weapon,if=target.time_to_die<=60&buff.potion.up
					-- actions+=/blood_fury
					-- actions+=/berserking
					-- actions+=/arcane_torrent
					-- actions+=/use_item,slot=trinket2
					-- actions+=/run_action_list,name=aoe,if=active_enemies>=3
					-- actions+=/run_action_list,name=single_target,if=active_enemies<3
					-- th = 4 aoe

					if GS.AoE and (GS.PlayerCount(10) >= 4 or OffhandHasWeapon() and GS.PlayerCount(10) >= 3) then
						if GS.PlayerHasTalent(1, 3) and GS.SIR(unholy_blight) then GS.Cast("target", unholy_blight, false, false, false, "SpellToInterrupt") return end -- unholy blight
						-- actions.aoe+=/blood_boil,if=dot.blood_plague.ticking&(!talent.unholy_blight.enabled|cooldown.unholy_blight.remains<49),line_cd=28
						-- actions.aoe+=/defile
						-- actions.aoe+=/breath_of_sindragosa,if=runic_power>75
						-- actions.aoe+=/run_action_list,name=bos_aoe,if=dot.breath_of_sindragosa.ticking
						if GS.SIR(49184) then -- howling blast
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 49184, false, false, false, "SpellToInterrupt")
							FacePosition(rot)
							return
						end
						if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 11) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap dump before you overflow
						if GS.SCA(49143, "target", interruptCasting) and GS.PP() > 88 then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike
						if not GS.PlayerHasTalent(7, 2) and GS.SIR(43265) and unholy == 1 then -- death and decay
							local x, y, z = GS.SmartAoE(30, 8, true)
							GS.Cast("target", 43265, x, y, z, "SpellToInterrupt")
							return
						end
						if GS.SCA(45462, "target", interruptCasting) and unholy == 2 then GS.Cast("target", 45462, false, false, false, "SpellToInterrupt") return end -- plague strike one unholy rune
						if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end
						if GS.SCA(49143, "target", interruptCasting) and (not GS.PlayerHasTalent(7, 3) or GS.SpellCDDuration(152279, nil) >= 10) then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike as long as it doesn't delay BoS
						if GS.PlayerHasTalent(1, 2) and GS.SCA(123693, "target", interruptCasting) and (GS.Aura("target", 155159, "", "PLAYER") or GS.Aura("target", 55095, "", "PLAYER") and GS.Aura("target", 55078, "", "PLAYER")) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech
						if GS.SCA(45462, "target", interruptCasting) and unholy == 1 then GS.Cast("target", 45462, false, false, false, "SpellToInterrupt") return end -- plague strike one unholy rune
						-- actions.aoe+=/empower_rune_weapon
					end

					if OffhandHasWeapon() then
						if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 11) and (GS.PP() > 76 or GS.PP() >= 20 and GS.Aura("player", 51124)) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end
					else
						if GS.PlayerHasTalent(1, 2) and GS.SCA(123693, "target", interruptCasting) and (GS.Aura("target", 155159, "", "PLAYER") and GS.AuraRemaining("target", 155159, 1, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER") and GS.Aura("target", 55095, "", "PLAYER") and (GS.AuraRemaining("target", 55095, 1, "", "PLAYER") or GS.AuraRemaining("target", 55078, 1, "", "PLAYER"))) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech
					end
					
					if GS.TTD[ObjectPointer("target")] and GS.SCA(130736) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 then GS.Cast(nil, 130736, nil) return end -- soul reaper
					if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and GS.TTD[ObjectPointer("target")] and (frost == 0 and death == 0) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 35 then GS.Cast(nil, 45529, nil) return end -- soul reaper

					if OffhandHasWeapon() then
						-- 	actions.single_target+=/breath_of_sindragosa,if=runic_power>75
						-- 	actions.single_target+=/run_action_list,name=bos_st,if=dot.breath_of_sindragosa.ticking
					end

					if GS.PlayerHasTalent(7, 2) and GS.SIR(152280) then -- defile
						local x, y, z = GS.SmartAoE(30, 8, true)
						GS.Cast("target", 152280, x, y, z, "SpellToInterrupt")
						return
					end
					if GS.PlayerHasTalent(4, 1) and GS.PlayerHasTalent(7, 2) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and (unholy+death<1) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap for defile

					if OffhandHasWeapon() then
						-- 	actions.single_target+=/howling_blast,if=talent.breath_of_sindragosa.enabled&cooldown.breath_of_sindragosa.remains<7&runic_power<88
						-- 	actions.single_target+=/obliterate,if=talent.breath_of_sindragosa.enabled&cooldown.breath_of_sindragosa.remains<3&runic_power<76
						-- 	actions.single_target+=/frost_strike,if=buff.killing_machine.react|runic_power>88
						-- 	actions.single_target+=/frost_strike,if=cooldown.antimagic_shell.remains<1&runic_power>=50&!buff.antimagic_shell.up
						-- 	actions.single_target+=/howling_blast,if=death>1|frost>1
						-- 	actions.single_target+=/unholy_blight,if=!disease.ticking
					else
						if GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and GS.Aura("player", 59052) and GS.Aura("player", 51124) and ((GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 155159, 5, "", "PLAYER")) or not GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 55095, 5, "", "PLAYER") and not GS.AuraRemaining("target", 55078, 5, "", "PLAYER")) then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast, rime killing machine dump if disease won'trun out
						if GS.SCA(49020, "target", interruptCasting) and GS.Aura("player", 51124) then GS.Cast("target", 49020, false, false, false, "SpellToInterrupt") return end -- obliterate with killing machine
						if GS.PlayerHasTalent(4, 1) and GS.Aura("player", 51124) and (frost+unholy+death < 2) and GS.AuraStacks("player", 114851, 5) and GS.SIR(45529) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap for killing machine
						if GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and GS.Aura("player", 59052) and not GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 55095, "", "PLAYER") then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast for frost fever
						-- 	actions.single_target+=/outbreak,if=!disease.max_ticking
						-- 	actions.single_target+=/unholy_blight,if=!disease.min_ticking
						-- 	actions.single_target+=/breath_of_sindragosa,if=runic_power>75
						-- 	actions.single_target+=/run_action_list,name=bos_st,if=dot.breath_of_sindragosa.ticking
						-- 	actions.single_target+=/obliterate,if=talent.breath_of_sindragosa.enabled&cooldown.breath_of_sindragosa.remains<7&runic_power<76
						-- 	actions.single_target+=/howling_blast,if=talent.breath_of_sindragosa.enabled&cooldown.breath_of_sindragosa.remains<3&runic_power<88
					end

					if not GS.PlayerHasTalent(7, 1) and GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and not GS.Aura("target", 55095, "", "PLAYER") then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast
					if GS.PlayerHasTalent(7, 1) and GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and not GS.Aura("target", 155159, "", "PLAYER") then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast

					if OffhandHasWeapon() then
						if not GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 55078, "", "PLAYER") and unholy > 0 and GS.SCA(45462, "target", interruptCasting) then GS.Cast("target", 45462, false, false, false, "SpellToInterrupt") return end -- plague strike put up blood plague
						if GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and GS.Aura("player", 59052) then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast
						if GS.SCA(49143, "target", interruptCasting) and GS.TierBonus("t17") >= 2 and (GS.PP() >= 50 and GS.SpellCDDuration(51271, nil) < 5) then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike tier 17 2 piece bonus
					else
						if not GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 55078, "", "PLAYER") and GS.SCA(45462, "target", interruptCasting) then GS.Cast("target", 45462, false, false, false, "SpellToInterrupt") return end -- plague strike for disease
						if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 11) and GS.PP() > 76 then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap dump before overflow
					end

					if GS.SCA(49143, "target", interruptCasting) and GS.PP() > 76 then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike dump more than 76 runic power

					if OffhandHasWeapon() then
						if GS.SCA(49020, "target", interruptCasting) and unholy > 0 and not GS.Aura("player", 51124) then GS.Cast("target", 49020, false, false, false, "SpellToInterrupt") return end -- obliterate dump
						-- 	actions.single_target+=/howling_blast,if=!(target.health.pct-3*(target.health.pct%target.time_to_die)<=35&cooldown.soul_reaper.remains<3)|death+frost>=2
						-- 	actions.single_target+=/blood_tap
						-- 	actions.single_target+=/plague_leech
					else
						if GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and GS.Aura("player", 59052) and ((GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 155159, 5, "", "PLAYER")) or not GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 55095, 5, "", "PLAYER") and not GS.AuraRemaining("target", 55078, 5, "", "PLAYER")) and (GS.DEATHKNIGHTFRAC(1) >= 1.8 or GS.DEATHKNIGHTFRAC(2) >= 1.8 or GS.DEATHKNIGHTFRAC(3) >= 1.8) then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast
						if GS.SCA(49020, "target", interruptCasting) and (GS.DEATHKNIGHTFRAC(1) >= 1.8 or GS.DEATHKNIGHTFRAC(2) >= 1.8 or GS.DEATHKNIGHTFRAC(3) >= 1.8) then GS.Cast("target", 49020, false, false, false, "SpellToInterrupt") return end -- obliterate to prevent rune capping
					-- 	actions.single_target+=/plague_leech,if=disease.min_remains<3&((blood.frac<=0.95&unholy.frac<=0.95)|(frost.frac<=0.95&unholy.frac<=0.95)|(frost.frac<=0.95&blood.frac<=0.95))
						if GS.PlayerHasTalent(4, 2) and GS.SCA(49143, "target", interruptCasting) and (frost == 0 or unholy == 0 or blood == 0) and (not GS.Aura("player", 51124) or GS.SpellCDDuration(49020, nil) > 1) then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike for runic empowerment if no killing aura or obliterate not up in a gcd
					-- 	actions.single_target+=/frost_strike,if=talent.blood_tap.enabled&buff.blood_charge.stack<=10&(!buff.killing_machine.react|!obliterate.ready_in<=1)
						if GS.SIR(49184) and GS.Distance("target", nil)-UnitCombatReach("target") <= 30 and GS.IsFacing("player", "target") and GS.Aura("player", 59052) and ((GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 155159, 5, "", "PLAYER")) or not GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 55095, 5, "", "PLAYER") and not GS.AuraRemaining("target", 55078, 5, "", "PLAYER")) then GS.Cast("target", 49184, false, false, false, "SpellToInterrupt") return end -- howling blast if diseases won't fall
						if GS.SCA(49020, "target", interruptCasting) and (GS.DEATHKNIGHTFRAC(1) >= 1.5 or GS.DEATHKNIGHTFRAC(2) >= 1.5 or GS.DEATHKNIGHTFRAC(3) >= 1.5 or GS.Bloodlust() or GS.PlayerHasTalent(1, 2) and GS.SpellCDDuration(123693, nil) <= 4) then GS.Cast("target", 49020, false, false, false, "SpellToInterrupt") return end -- obliterate to prevent rune capping or under bloodlust or if plague leech is about to come up
					-- 	actions.single_target+=/blood_tap,if=(buff.blood_charge.stack>10&runic_power>=20)|(blood.frac>=1.4|unholy.frac>=1.6|frost.frac>=1.6)
						if GS.SCA(49143, "target", interruptCasting) and not GS.Aura("player", 51124) then GS.Cast("target", 49143, false, false, false, "SpellToInterrupt") return end -- frost strike if no killing machine buff
					-- 	actions.single_target+=/plague_leech,if=(blood.frac<=0.95&unholy.frac<=0.95)|(frost.frac<=0.95&unholy.frac<=0.95)|(frost.frac<=0.95&blood.frac<=0.95)
					end

					-- actions.single_target+=/empower_rune_weapon
				end
			end

			-- actions.bos_aoe=howling_blast
			-- actions.bos_aoe+=/blood_tap,if=buff.blood_charge.stack>10
			-- actions.bos_aoe+=/death_and_decay,if=unholy=1
			-- actions.bos_aoe+=/plague_strike,if=unholy=2
			-- actions.bos_aoe+=/blood_tap
			-- actions.bos_aoe+=/plague_leech
			-- actions.bos_aoe+=/plague_strike,if=unholy=1
			-- actions.bos_aoe+=/empower_rune_weapon

			-- actions.bos_st=obliterate,if=buff.killing_machine.react
			-- actions.bos_st+=/blood_tap,if=buff.killing_machine.react&buff.blood_charge.stack>=5
			-- actions.bos_st+=/plague_leech,if=buff.killing_machine.react
			-- if oh then
			-- 	actions.bos_st+=/howling_blast,if=runic_power<88
			-- 	actions.bos_st+=/obliterate,if=unholy>0&runic_power<76
			-- end
			-- actions.bos_st+=/blood_tap,if=buff.blood_charge.stack>=5
			-- actions.bos_st+=/plague_leech
			-- if oh then
			-- 	actions.bos_st+=/empower_rune_weapon
			-- elseif th then
			-- 	actions.bos_st+=/obliterate,if=runic_power<76
			-- 	actions.bos_st+=/howling_blast,if=((death=1&frost=0&unholy=0)|death=0&frost=1&unholy=0)&runic_power<88
			-- end
		end

	function GS.DEATHKNIGHT3() -- unholy  -- todo: add trinket
		if GetShapeshiftForm() ~= 3 then CastShapeshiftForm(3) return end
		if not GS.Combat() and GS.SIR(57330) and not IsMounted() and not GetRaidBuffTrayAuraInfo(3) then GS.Cast("player", 57330, nil) return end -- horn of winter

		if GS.Combat() then
			local blood, frost, unholy = GS.RuneCheck("slot")
			local _, _, _, death = GS.Runes()
			if not GS.PlayerHasTalent(7, 1) then
				GS.MultiDoT("Blood Plague")
				GS.MultiDoT("Frost Fever")
			else
				GS.MultiDoT("Necrotic Plague")
			end

			if GS.ValidTarget() then
				StartAttack("target")
				if GS.SCA(49998) and GS.DeathStrike then
					GS.Cast(nil, 49998)
					GS.DeathStrike = false
					return
				end -- death strike

				if GS.CDs and GSR.Race == "Orc" and GS.UnitIsBoss("target") and GS.SIR(20572) then GS.Cast("player", 20572, nil) return end -- blood fury
				if GS.CDs and GSR.Race == "Troll" and GS.UnitIsBoss("target") and GS.SIR(26297) then GS.Cast(nil, 26297) return end -- berserking
				if GS.CDs and GSR.Race == "BloodElf" and GS.UnitIsBoss("target") and GS.SIR(50613) then GS.Cast("player", 50613, nil) return end -- arcane torrent

				-- actions+=/use_item,slot=trinket2

				-- actions+=/potion,name=draenic_strength,if=buff.dark_transformation.up&target.time_to_die<=60

				if GS.AoE and (not GS.PlayerHasTalent(7, 1) and GS.PlayerCount(10) >= 2 or GS.PlayerHasTalent(7, 1) and GS.PlayerCount(10) >= 4) then
					if GS.PlayerHasTalent(1, 3) and GS.SIR(115989) then GS.Cast(nil, 115989, nil) return end -- unholy blight

					if (GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.Aura("target", 55095, "", "PLAYER") or not GS.Aura("target", 55078, "", "PLAYER")) then
						if not GS.PlayerHasTalent(7, 1) and GS.SIR(50842) then
							for i = 1, #tNoObjectBloodPlague do
								if GS.Distance(tNoObjectBloodPlague[i], nil) <= 10 then
									for i = 1, #tBloodPlague do
										if GS.Distance(tBloodPlague[i], nil) <= 10 then
											GS.Cast("target", 50842, false, false, false, "SpellToInterrupt")
											return
										end
									end
								end
							end
							for i = 1, #tNoObjectFrostFever do
								if GS.Distance(tNoObjectFrostFever[i], nil) <= 10 then
									for i = 1, #tFrostFever do
										if GS.Distance(tFrostFever[i], nil) <= 10 then
											GS.Cast("target", 50842, false, false, false, "SpellToInterrupt")
											return
										end
									end
								end
							end
						end
						if GS.SIR(77575) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (not GS.Aura("target", 55095, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER")))) then GS.Cast("target", 77575, false, false, false, "SpellToInterrupt") return end -- outbreak
						if GS.SCA(45462) and not GS.Aura("player", 115989) and not GS.Aura("target", 55078, "", "PLAYER") and not GS.Aura("target", 155159, "", "PLAYER") then GS.Cast(nil, 45462, nil) return end -- plague strike
					end

					if GS.PlayerHasTalent(7, 2) and GS.SIR(152280) then GS.Cast(nil, 152280, GS.SmartAoE(30, 8, true)) return end -- defile
					if GS.PlayerHasTalent(7, 3) and not GS.Aura("player", 152279) and GS.SIR(152279) and GS.PP() > 75 then GS.Cast(nil, 152279, nil) return end -- breath of sindragosa turn on
					if GS.Aura("player", 152279) then GS.DEATHKNIGHTBOS("aoe", blood, frost, unholy, death) return end -- call bos rotation
					if GS.SIR(50842) and (blood == 2 or (frost == 2 and death == 2)) then GS.Cast(nil, 50842) return end -- blood boil
					if GS.CDs and GS.SIR(49206) and GS.UnitIsBoss("target") then GS.Cast(nil, 49206) return end -- summon gargoyle
					if GS.SIR(63560) then GS.Cast(nil, 63560) return end -- dark transformation
					if GS.PlayerHasTalent(4, 1) and GS.AuraStacks("player", 91342, 5) and GS.AuraStacks("player", 114851, 5) and GS.SIR(45529) then GS.Cast(nil, 45529, nil) return end -- blood tap for transformation
					if not GS.PlayerHasTalent(7, 2) and GS.SIR(43265) and unholy == 1 then GS.Cast("player", 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
					if GS.TTD[ObjectPointer("target")] and GS.SCA(130736) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 45 then GS.Cast(nil, 130736, nil) return end -- soul reaper
					if GS.SCA(55090) and unholy == 2 then GS.Cast(nil, 55090) return end -- scourge strike
					if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 11) then GS.Cast(nil, 45529, nil) return end -- blood tap dump
					if GS.SCA(47541) and (GS.PP() > 90 or GS.Aura("player", 81340) or (not GS.Aura("pet", 63560) and unholy <= 1)) then GS.Cast(nil, 47541) return end -- death coil
					if GS.SIR(50842) then GS.Cast(nil, 50842) return end -- blood boil
					if GS.SCA(45477) then GS.Cast(nil, 45477) return end -- icy touch
					if GS.SCA(55090) and unholy == 1 then GS.Cast(nil, 55090) return end -- scourge strike
					if GS.SCA(47541) then GS.Cast(nil, 47541) return end -- death coil
					if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and (blood == 0 or frost == 0 or unholy == 0) then GS.Cast(nil, 45529, nil) return end -- blood tap
					if GS.PlayerHasTalent(1, 2) and GS.SIR(123693) and unholy == 1 then GS.Cast(nil, 123693, nil) return end -- plague leech
					if GS.CDs and GS.SIR(47568) and GS.UnitIsBoss("target") and blood == 0 and unholy == 0 and frost == 0 and death == 0 then GS.Cast(nil, 47568) return end -- empower rune weapon
					return
				end

				if GS.PlayerHasTalent(1, 2) and GS.SCA(123693) and (GS.Aura("target", 55095, "", "PLAYER") and GS.Aura("target", 55078, "", "PLAYER") or GS.Aura("target", 155159, "", "PLAYER")) and GS.SpellCDDuration(77575, nil) < 1 and ((blood<1 and frost<1) or (blood<1 and unholy<1) or (frost<1 and unholy<1)) then GS.Cast(nil, 123693, nil) return end -- plague leech outbreak
				if GS.PlayerHasTalent(1, 2) and GS.SCA(123693) and (GS.Aura("target", 55095, "", "PLAYER") and GS.Aura("target", 55078, "", "PLAYER") or GS.Aura("target", 155159, "", "PLAYER")) and ((blood<1 and frost<1) or (blood<1 and unholy<1) or (frost<1 and unholy<1)) and ((not GS.PlayerHasTalent(7, 1) and (GS.AuraRemaining("target", 55078, 3, "", "PLAYER") or GS.AuraRemaining("target", 55095, 3, "", "PLAYER"))) or (GS.PlayerHasTalent(7, 1) and GS.AuraRemaining("target", 155159, 3, "", "PLAYER"))) then GS.Cast(nil, 123693, nil) return end -- plague leech dots running out
				if GS.PlayerHasTalent(1, 2) and GS.SCA(123693) and (GS.Aura("target", 55095, "", "PLAYER") and GS.Aura("target", 55078, "", "PLAYER") or GS.Aura("target", 155159, "", "PLAYER")) and (blood < 1 or frost < 1 or unholy < 1) and ((not GS.PlayerHasTalent(7, 1) and (GS.AuraRemaining("target", 55078, 1, "", "PLAYER") or GS.AuraRemaining("target", 55095, 1, "", "PLAYER"))) or (GS.PlayerHasTalent(7, 1) and GS.AuraRemaining("target", 155159, 1, "", "PLAYER"))) then GS.Cast(nil, 123693, nil) return end -- plague leech dots running out
				if GS.SIR(77575) and not GS.Aura("player", 115989) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (not GS.Aura("target", 55078, "", "PLAYER") or not GS.Aura("target", 55095, "", "PLAYER")))) then GS.Cast("target", 77575, nil) return end -- outbreak
				if GS.PlayerHasTalent(1, 3) and GS.SIR(115989) and ((GS.PlayerHasTalent(7, 1) and GS.AuraRemaining("target", 155159, 1, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (GS.AuraRemaining("target", 55078, 3, "", "PLAYER") or GS.AuraRemaining("target", 55095, 3, "", "PLAYER")))) then GS.Cast("target", 115989, nil) return end -- unholy blight
				if GS.SCA(47541) and GS.PP() > 90 then GS.Cast(nil, 47541) return end -- death coil
				if GS.TTD[ObjectPointer("target")] and GS.SCA(130736) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 45 then GS.Cast(nil, 130736, nil) return end -- soul reaper
				if GS.PlayerHasTalent(7, 3) and GS.SIR(152279) and GS.Distance("target", nil) <= 12+UnitCombatReach("target") and GS.IsFacing("player", "target") and GS.UnitIsBoss("target") and GS.PP() > 75 then GS.Cast("target", 152279, false, false, false, "SpellToInterrupt") return end -- bos
				if GS.Aura("player", 152279) then GS.DEATHKNIGHTBOS("single", blood, frost, unholy, death) return end -- call bos rotation
				if GS.PlayerHasTalent(7, 3) and GS.SpellCDDuration(152279, nil) < 7 then
					if GS.PP() < 88 then
						if GS.SIR(43265) then GS.Cast("player", 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
						if GS.SCA(55090) then GS.Cast(nil, 55090) return end -- scourge strike
					elseif GS.PP() < 76 then
						if GS.SCA(85948) then GS.Cast(nil, 85948) return end -- festering strike
					end
				end
				if GS.TTD[ObjectPointer("target")] and GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 45 and GS.SpellCDDuration(130736, nil) == 0 then GS.Cast(nil, 45529, nil) return end -- blodo tap for soul reaper
				if not GS.PlayerHasTalent(7, 2) and GS.SIR(43265) and unholy == 2 then GS.Cast("player", 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152280) and unholy == 2 then GS.Cast("player", 152280, GS.SmartAoE(30, 8, true)) return end -- defile
				if GS.SCA(45462) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (not GS.Aura("target", 55078, "", "PLAYER") or not GS.Aura("target", 55095, "", "PLAYER")))) and unholy == 2 then GS.Cast(nil, 45462) return end -- plague strike if no blood plague frost fever
				if GS.SCA(55090) and unholy == 2 then GS.Cast(nil, 55090) return end -- scourge strike
				if GS.SCA(47541) and GS.PP() > 80 then GS.Cast(nil, 47541) return end -- death coil
				if GS.SCA(85948, "target", interruptCasting) and GS.PlayerHasTalent(7, 1) and GS.PlayerHasTalent(1, 3) and GS.Aura("target", 155159, "", "PLAYER") and GS.AuraRemaining("target", 155159, GS.SpellCDDuration(115989, nil)/2) then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering strike keep up necrotic plague
				if GS.SCA(85948, "target", interruptCasting) and blood == 2 and frost == 2 and (((GS.RuneCheck("available", "Frost")-death)>0) or ((GS.RuneCheck("available", "Blood")-death)>0)) then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering strike
				if GS.SCA(85948, "target", interruptCasting) and (blood == 2 or frost == 2) and (GS.RuneCheck("available", "Frost")-death > 0 and GS.RuneCheck("available", "Blood")-death > 0) then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering strike
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152280) and (blood == 2 or frost == 2) then GS.Cast("player", 152280, GS.SmartAoE(30, 8, true)) return end -- defile
				if GS.SCA(45462) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (not GS.Aura("target", 55078, "", "PLAYER") or not GS.Aura("target", 55095, "", "PLAYER")))) and (frost == 2 or blood == 2) then GS.Cast(nil, 45462) return end -- plague strike if no blood plague frost fever
				if GS.SCA(55090) and (blood == 2 or frost == 2) then GS.Cast(nil, 55090) return end -- scourge strike
				if GS.SCA(85948, "target", interruptCasting) and GS.RuneCheck("available", "Blood")-death > 1 then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering dump blood
				if GS.SIR(50842) and GS.PlayerCount(10) > 0 and GS.RuneCheck("available", "Blood")-death > 1 then GS.Cast("target", 50842, false, false, false, "SpellToInterrupt") return end -- blood boil
				if GS.SCA(85948, "target", interruptCasting) and GS.RuneCheck("available", "Frost")-death > 1 then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering dump frost
				if GS.CDs and GS.SIR(49206) and GS.UnitIsBoss("target") then GS.Cast(nil, 49206) return end -- summon gargoyle
				if not GS.PlayerHasTalent(7, 2) and GS.SIR(43265) then GS.Cast("player", 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152280) then GS.Cast("player", 152280, GS.SmartAoE(30, 8, true)) return end -- defile
				if GS.PlayerHasTalent(7, 2) and GS.SpellCDDuration(152280, nil) == 0 and GS.PlayerHasTalent(4, 1) and GS.AuraStacks("player", 114851, 5) and GS.SIR(45529) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap for defile
				if GS.SCA(45462) and ((GS.PlayerHasTalent(7, 1) and not GS.Aura("target", 155159, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and (not GS.Aura("target", 55078, "", "PLAYER") or not GS.Aura("target", 55095, "", "PLAYER")))) then GS.Cast(nil, 45462) return end -- plague strike if no blood plague frost fever
				if GS.SIR(63560) then GS.Cast(nil, 63560) return end -- dark transformation
				if GS.PlayerHasTalent(4, 1) and GS.AuraStacks("player", 114851, 11) and GS.SIR(45529) and (GS.Aura("player", 81340) or not GS.Aura("pet", 63560) and unholy <= 1) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap dump pet
				if GS.SCA(47541) and (GS.Aura("player", 81340) or (not GS.Aura("pet", 63560) and unholy <= 1)) then GS.Cast(nil, 47541) return end -- death coil
				if GS.SCA(55090) and (unholy >= 2 or not (GS.TTD[ObjectPointer("target")] and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 45)) then GS.Cast(nil, 55090) return end -- scourge strike dump no execute
				if GS.PlayerHasTalent(4, 1) and GS.SIR(45529) and GS.AuraStacks("player", 114851, 5) and (blood == 0 or frost == 0 or unholy == 0) then GS.Cast("target", 45529, false, false, false, "SpellToInterrupt") return end -- blood tap nothing else
				if GS.SCA(58948, "target", interruptCasting) and (not (GS.TTD[ObjectPointer("target")] and GS.Health("target", nil, true) - 3 * (GS.Health("target", nil, true)/GS.TTD[ObjectPointer("target")]) <= 45) or (GS.RuneCheck("available", "Blood")-death > 0 and GS.RuneCheck("available", "Frost")-death > 0)) then GS.Cast("target", 58948, false, false, false, "SpellToInterrupt") return end -- festering dump no execute
				if GS.SCA(47541) then GS.Cast(nil, 47541) return end -- death coil
				if GS.PlayerHasTalent(1, 2) and GS.SCA(123693, "target", interruptCasting) and (GS.Aura("target", 155159, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER") and GS.Aura("target", 55095, "", "PLAYER")) and ((blood == 0 and unholy == 0) or (blood == 0 and frost == 0) or (unholy == 0 and frost == 0)) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech nothing else
				if GS.CDs and GS.SpellCDDuration(47568, nil) == 0 then
					if GS.SCA(55090, "target", interruptCasting) then GS.Cast("target", 55090, false, false, false, "SpellToInterrupt") return end -- scourge strike dump
					if GS.SCA(85948, "target", interruptCasting) then GS.Cast("target", 85948, false, false, false, "SpellToInterrupt") return end -- festering strike dump
					if GS.SIR(50842) and GS.PlayerCount() > 0 then GS.Cast("target", 50842, false, false, false, "SpellToInterrupt") return end -- blood boil dump
					if GS.SCA(45477, "target", interruptCasting) then GS.Cast("target", 45477, false, false, false, "SpellToInterrupt") return end -- icy touch dump
				end
				if GS.CDs and GS.SIR(47568) and GS.UnitIsBoss("target") and blood == 0 and unholy == 0 and frost == 0 and death == 0 then GS.Cast(nil, 47568) return end -- empower rune weapon
			end
		end
	end

	function GS.SHAMAN1() -- elemental -- todo: vomit at the earthquakes, moving, totem management @shaman
		if not GS.Aura("player", 324) and not IsMounted() then GS.Cast("player", 324, false, false, false, "SpellToInterrupt") return end
		if GS.Combat() then
			if GS.ValidTarget() then

				if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) and not GS.Bloodlust() and not GS.Aura("player", 16166) and (GS.SpellCDDuration(165339, nil) == 0 and not GS.AuraRemaining("target", 8050, 15, "", "PLAYER")) and GS.SpellCDDuration(61304, nil) == 0 then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") return end -- berserking
				if GS.CDs and GSR.Race == "Orc" and GS.SIR(33697) and (GS.Bloodlust() or GS.Aura("player", 114050) or (GS.SpellCDDuration(2894, nil) > 10 and GS.SpellCDDuration(165339, nil) > 10)) then GS.Cast("target", 33697, false, false, false, "SpellToInterrupt") return end -- blood fury

				if GS.CDs and GS.SpellCDDuration(61304, nil) == 0 and GS.PlayerHasTalent(4, 1) and GS.SIR(16166) and select(4, GetSpellInfo(51505))*0.001 >= 1.2 then GS.Cast("target", 16166, false, false, false, "SpellToInterrupt") end -- elemental mastery

				if GS.CDs and GS.PlayerHasTalent(4, 2) and GS.SIR(16188) and not GS.Aura("player", 114050) then GS.Cast("target", 16188, false, false, false, "SpellToInterrupt") return end -- ancestral swiftness
				if GS.CDs and GS.PlayerHasTalent(7, 2) and GS.SIR(152256) then GS.Cast("target", 152256, false, false, false, "SpellToInterrupt") return end -- storm elemental totem
				if GS.CDs and GS.SIR(2894) and GetTotemInfo(1) == false then GS.Cast("target", 2894, false, false, false, "SpellToInterrupt") return end -- Fire Elemental Totem
				if GS.CDs and GS.SIR(165339) and GS.UnitIsBoss("target") and (not GS.AuraRemaining("target", 8050, 15)) and (GS.SpellCDDuration(51505, nil) > 0 and (GS.Bloodlust() or GS.TTD[ObjectPointer("target")] < 20 or (GetTime()-GS.CombatStart) > 60)) then GS.Cast("target", 165339, false, false, false, "SpellToInterrupt") end -- ascendance
				if GS.PlayerHasTalent(7, 3) and GS.SIR(152255) and GetTotemTimeLeft(1) >= 15 then GS.Cast("target", 152255, false, false, false, "SpellToInterrupt") return end -- liquid magma
				
				if GS.AoE and GS.TargetCount(8) > 1 then
					if GS.SIR(61882) and GetUnitSpeed("target") == 0 and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 79206)) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end -- earthquake
					if GS.SCA(421, "target", interruptCasting) and GS.Aura("player", 114050) then GS.Cast("target", 421, false, false, false, "SpellToInterrupt") return end -- chain lightning ascendance
					if GS.SCA(8042, "target") and ((IsSpellKnown(157774) and GS.AuraStacks("player", 324, 20)) or GS.AuraStacks("player", 324, 15)) then GS.Cast("target", 8042, nil) return end -- earth shock max dump
					if GS.SIR(51490) and GS.PlayerCount(10) >= 10 then GS.Cast("target", 51490, false, false, false, "SpellToInterrupt") return end -- thunderstorm
					if GS.SIR(3599) then -- searing totem
						if not GS.PlayerHasTalent(7, 3) then
							if GetTotemInfo(1) == false then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end
						else
							if GetTotemInfo(1) == false or (not GS.Aura("player", 152255) and select(2, GetTotemInfo(1)) == "Searing Totem" and GetTotemTimeLeft(1) <= 20) then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(421, "target", interruptCasting) then GS.Cast("target", 421, false, false, false, "SpellToInterrupt") return end -- chain lightning
					if GS.SCA(403, "target") then GS.Cast("target", 403, nil) return end -- lightning bolt
					return
				end

				if GS.SIR(165462) and IsPlayerMoving() and not GS.Aura("player", 79206) and not GS.Aura("player", 172106) then GS.Cast("player", 165462, false, false, false, "SpellToInterrupt") return end -- unleash flame
				if GS.CDs and GS.SIR(79206) and IsPlayerMoving() and GS.Aura("player", 114050) and not GS.Aura("player", 172106) then GS.Cast("target", 79206, false, false, false, "SpellToInterrupt") return end -- spiritwalker's grace
				if GS.SCA(8042, "target") and ((IsSpellKnown(157774) and GS.AuraStacks("player", 324, 20)) or GS.AuraStacks("player", 324, 15)) then GS.Cast("target", 8042, nil) return end -- earth shock max dump
				if GS.SCA(51505, "target") and (not IsPlayerMoving() or GS.Aura("player", 77756)) and not GS.AuraRemaining("target", 8050, select(4, GetSpellInfo(51505))*.001, "", "PLAYER") then GS.Cast("target", 51505, nil) return end -- lava burst if flame shock
				if GS.PlayerHasTalent(6, 1) and GS.SIR(165462) and not GS.Aura("player", 114050) then GS.Cast("player", 165462, false, false, false, "SpellToInterrupt") return end -- unleash flame
				if GS.SCA(8050, "target") and GS.AuraRemaining("target", 8050, 9, "", "PLAYER") then GS.Cast("target", 8050, nil) return end -- flame shock
				if GS.SCA(8042, "target") and ((GS.TierBonus("t17") >= 4 and not GS.Aura("player", 77762) and GS.AuraStacks("player", 324, 15)) or (GS.TierBonus("t17") < 4 and GS.AuraStacks("player", 324, 16))) then GS.Cast("target", 8042, nil) return end -- earth shock set bonuses or dump
				if GS.PlayerHasTalent(6, 1) and (not IsPlayerMoving() or GS.Aura("player", 79206) or GS.Aura("player", 172106)) and not GetUnitSpeed("target") > 0 then 
					if GS.SIR(61882) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 10 then
						if not GS.Bloodlust() and not GS.Aura("player", 16166) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 / 4.5)) >= (2.72038125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
						if (GS.Bloodlust() or GS.Aura("player", 16166)) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 / 4.5)) >= 1.3 * (2.72038125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
						if (GS.Bloodlust() or (GS.Aura("player", 16166) and not GS.AuraRemaining("player", 16166, 10))) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 / 4.5)) >= (2.72038125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
					end
				elseif (not IsPlayerMoving() or GS.Aura("player", 79206) or GS.Aura("player", 172106)) and not GetUnitSpeed("target") > 0 then
					if GS.SIR(61882) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 10 then
						if not GS.Bloodlust() and not GS.Aura("player", 16166) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 % 4.5)) >= (2.15788125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
						if (GS.Bloodlust() or GS.Aura("player", 16166)) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 % 4.5)) >= 1.3 * (2.15788125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
						if (GS.Bloodlust() or (GS.Aura("player", 16166) and not GS.AuraRemaining("player", 16166, 10))) and ((1 + (1/(1+GetHaste()*.01))) * (1 + (GetMasteryEffect() * 2 % 4.5)) >= (2.15788125 + 1.25 * (0.0045261 * GetMultistrike()))) then GS.Cast("target", 61882, false, false, false, "SpellToInterrupt") return end
					end
				end
				if GS.PlayerHasTalent(6, 3) and GS.SCA(117014, "target") then GS.Cast("target", 117014, nil) return end -- elemental blast
				if GS.SCA(8050, "target", interruptCasting) and GS.AuraRemaining("player", 8050, 15) and GS.SpellCDDuration(165339, nil)+15 < 30 then GS.Cast("target", 8050, false, false, false, "SpellToInterrupt") return end -- flame shock ascendance

				if GS.SIR(3599) then -- searing totem
					if not GS.PlayerHasTalent(7, 3) then
						if GetTotemInfo(1) == false then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end
					else
						if GetTotemInfo(1) == false or (not GS.Aura("player", 152255) and select(2, GetTotemInfo(1)) == "Searing Totem" and GetTotemTimeLeft(1) <= 20) then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end
					end
				end

				if GS.SIR(79206) and IsPlayerMoving() and ((GS.PlayerHasTalent(6, 3) and GS.SpellCDDuration(117014, nil) == 0) or (GS.SpellCDDuration(51505, nil) == 0 and not GS.Aura("player", 77762))) then GS.Cast("target", 79206, false, false, false, "SpellToInterrupt") return end -- spiritwalker's grace
				if GS.SCA(403, "target") then GS.Cast("target", 403, nil) return end -- lightning bolt
			end
		end
	end

	function GS.SHAMAN2() -- enhance todo: cooldowns trinket, @aoe magma totem elemental blast
		if GS.SIR(324) and not GS.Aura("player", 324) and not IsMounted() then GS.Cast("player", 324, false, false, false, "SpellToInterrupt") return end
		if GS.Combat() then
			GS.MultiDoT("Flame Shock")
			if GS.ValidTarget() then
				StartAttack("target")

				-- actions+=/use_item,name=beating_heart_of_the_mountain
				-- actions+=/potion,name=draenic_agility,if=(talent.storm_elemental_totem.enabled&pet.storm_elemental_totem.remains>=25)|(!talent.storm_elemental_totem.enabled&pet.fire_elemental_totem.remains>=25)|target.time_to_die<=30
				-- actions+=/blood_fury
				-- actions+=/arcane_torrent
				-- actions+=/berserking

				if GS.CDs and GS.PlayerHasTalent(4, 1) and GS.SIR(16166) then GS.Cast("target", 16166, false, false, false, "SpellToInterrupt") return end -- elemental mastery
				
				-- actions+=/storm_elemental_totem

				if GS.CDs and GS.SIR(2894) and not GetTotemInfo(1) and ((GS.PlayerHasTalent(6, 2) and #GS.PullEnemies(30, true) <= 10) or #GS.PullEnemies(30, true) <= 6) then GS.Cast("target", 2894, false, false, false, "SpellToInterrupt") return end

				if GS.CDs and GS.SIR(165341) then GS.Cast("target", 165341, false, false, false, "SpellToInterrupt") return end -- ascendance
				if GS.CDs and GS.SIR(51533) then GS.Cast("target", 51533, false, false, false, "SpellToInterrupt") return end -- feral spirit
				if GS.PlayerHasTalent(7, 3) and GS.SIR(152255) then
					local _, _, start, duration = GetTotemInfo(1)
					local totemTimeRemaining = duration-(GetTime()-start)
					if totemTimeRemaining >= 15 then GS.Cast("target", 152255, false, false, false, "SpellToInterrupt") return end
				end
				if GS.PlayerHasTalent(4, 2) and GS.SIR(16188) then GS.Cast("target", 16188, false, false, false, "SpellToInterrupt") return end -- ancestral swiftness
				
				if GS.AoE and #GS.PullEnemies(30, true) > 1 then
					if GS.SIR(73680) and #GS.PullEnemies(30, true) >= 4 and GS.Aura("target", 8050, "", "PLAYER") and (GS.SpellCDDuration(8050, nil) > GS.SpellCDDuration(1535, nil) or GS.SpellCDDuration(1535, nil) == 0) then GS.Cast("target", 73680, false, false, false, "SpellToInterrupt") return end -- unleash comments
					if GS.SIR(1535) and #tFlameShock >= 3 then GS.Cast("target", 1535, false, false, false, "SpellToInterrupt") return end -- fire nova
					if #tFlameShock >= 4 and GS.SpellCDDuration(1535, nil) <= (1.5/(1+GetHaste()*.001)) then return end -- wait for fire nova

					-- if not GetTotemInfo(1) and GS.SIR(8190) then GS.Cast("target", 8190, false, false, false, "SpellToInterrupt") return end -- magma totem
					if GS.SCA(60103, "target", interruptCasting) and GS.Aura("target", 8050, "", "PLAYER") and ((#tFlameShock < GS.TargetCount(12) or GS.PlayerHasGlyph(159644) and #tFlameShock < GS.TargetCount(20)) or not GS.PlayerHasTalent(4, 3) or not GS.Aura("player", 159103)) then GS.Cast("target", 60103, false, false, false, "SpellToInterrupt") return end -- lava lash
					-- actions.aoe+=/elemental_blast,if=!buff.unleash_flame.up&(buff.maelstrom_weapon.react>=4|buff.ancestral_swiftness.up)
					if GS.SCA(421, "target", interruptCasting) and GS.PlayerHasGlyph(55449) and GS.TargetCount(8) >= 4 and (GS.AuraStacks("player", 53817, 5) or (GS.Aura("player", 16188) and GS.AuraStacks("player", 53817, 3))) then GS.Cast("target", 421, false, false, false, "SpellToInterrupt") return end -- chain lightning
					if #GS.PullEnemies(30, true) < 4 and GS.SIR(73680) then GS.Cast("player", 73680, false, false, false, "SpellToInterrupt") return end -- unleash elements
					if GS.SIR(8050) then -- flame shock cycle
						if GS.SCA(8050, "target", interruptCasting) and not GS.Aura("target", 8050, "", "PLAYER") then GS.Cast("target", 8050, false, false, false, "SpellToInterrupt") return end -- flame shock target
						for i = 1, #tNoObjectFlameShock do
							if GS.SCA(8050, tNoObjectFlameShock[i], interruptCasting) then GS.Cast(tNoObjectFlameShock[i], 8050, false, false, false, "SpellToInterrupt") return end
						end
					end
					if GS.SCA(403, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106)) and (not GS.PlayerHasGlyph(55449) or GS.TargetCount(8) <= 3) and (GS.AuraStacks("player", 53817, 5) or (GS.Aura("player", 16188) and GS.AuraStacks("player", 53817, 3))) then GS.Cast("target", 403, false, false, false, "SpellToInterrupt") return end -- lightning bolt
					if GS.SCA(115356, "target", interruptCasting) then GS.Cast("target", 115356, false, false, false, "SpellToInterrupt") return end -- windstrike
					-- actions.aoe+=/elemental_blast,if=!buff.unleash_flame.up&buff.maelstrom_weapon.react>=1
					if GS.SCA(421, "target", interruptCasting) and GS.PlayerHasGlyph(55449) and GS.TargetCount(8) >= 4 and GS.Aura("player", 53817) then GS.Cast("target", 421, false, false, false, "SpellToInterrupt") return end -- chain lightning
					if GS.SIR(1535) and #tFlameShock >= 2 then GS.Cast("target", 1535, false, false, false, "SpellToInterrupt") return end
					-- actions.aoe+=/magma_totem,if=pet.magma_totem.remains<=20&!pet.fire_elemental_totem.active&!buff.liquid_magma.up
					if GS.SCA(17364, "target", interruptCasting) then GS.Cast("target", 17364, false, false, false, "SpellToInterrupt") return end -- stormstrike
					if #GS.PullEnemies(30, true) < 4 and GS.SCA(8056, "target", interruptCasting) then GS.Cast("target", 8056, false, false, false, "SpellToInterrupt") return end -- frost shock
					if GS.PlayerHasTalent(6, 3) and GS.SCA(117014, "target", interruptCasting) and GS.Aura("player", 53817) then GS.Cast("target", 117014, false, false, false, "SpellToInterrupt") return end -- elemental blast
					if GS.SCA(421, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106)) and GS.TargetCount(8) >= 3 and GS.Aura("player", 53817) then GS.Cast("target", 421, false, false, false, "SpellToInterrupt") return end -- chain lightning
					if GS.SCA(403, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106)) and GS.TargetCount(8) < 3 and GS.Aura("player", 53817) then GS.Cast("target", 403, false, false, false, "SpellToInterrupt") return end -- lightning bolt
					if GS.SIR(1535) and #tFlameShock >= 1 then GS.Cast("target", 1535, false, false, false, "SpellToInterrupt") return end
					return
				end

				if GS.SIR(3599) and not GetTotemInfo(1) then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end -- searing totem
				if GS.PlayerHasTalent(6, 1) and GS.SIR(73680) then GS.Cast("player", 73680, false, false, false, "SpellToInterrupt") return end -- unleash elements
				if GS.PlayerHasTalent(6, 3) and GS.SCA(117014, "target", interruptCasting) and (GS.AuraStacks("player", 53817, 4) or GS.Aura("player", 16188)) then GS.Cast("target", 117014, false, false, false, "SpellToInterrupt") return end -- elemental blast
				if GS.SCA(115356, "target", interruptCasting) then GS.Cast("target", 115356, false, false, false, "SpellToInterrupt") return end -- windstrike
				if GS.SCA(403, "target", interruptCasting) and GS.AuraStacks("player", 53817, 5) then GS.Cast("target", 403, false, false, false, "SpellToInterrupt") return end -- lightning bolt
				if GS.SCA(17364, "target", interruptCasting) then GS.Cast("target", 17364, false, false, false, "SpellToInterrupt") return end -- stormstrike
				if GS.SCA(60103, "target", interruptCasting) then GS.Cast("target", 60103, false, false, false, "SpellToInterrupt") return end -- lava lash
				if GS.SCA(8050, "target", interruptCasting) and ((GS.PlayerHasTalent(7, 1) and GS.AuraStacks("player", 157174, 2) and GS.Aura("player", 73683) and GS.Aura("target", 8050, "", "PLAYER") and GS.AuraRemaining("target", 8050, 16, "", "PLAYER")) or (not GS.PlayerHasTalent(7, 1) and GS.Aura("player", 73683) and GS.Aura("target", 8050) and GS.AuraRemaining("target", 8050, 9, "", "PLAYER")) or not GS.Aura("target", 8050)) then GS.Cast("target", 8050, false, false, false, "SpellToInterrupt") return end -- flame shock
				if GS.SIR(73680) then GS.Cast("player", 73680, false, false, false, "SpellToInterrupt") return end -- unleash elements
				if GS.SCA(8056, "target", interruptCasting) and ((GS.PlayerHasTalent(7, 1) and not GS.AuraRemaining("target", 8050, 16, "", "PLAYER")) or not GS.PlayerHasTalent(7, 1)) then GS.Cast("target", 8056, false, false, false, "SpellToInterrupt") return end -- frost shock
				if GS.PlayerHasTalent(6, 3) and GS.SCA(117014, "target", interruptCasting) and GS.Aura("player", 53817) then GS.Cast("target", 117014, false, false, false, "SpellToInterrupt") return end -- elemental blast
				if GS.SCA(403, "target", interruptCasting) and ((select(4, GetSpellInfo(403))*0.001) < GS.SpellCDDuration(60103, nil) and (select(4, GetSpellInfo(603))*0.001 < GS.SpellCDDuration(17364, nil)) and (not GS.Aura("player", 114051) or (select(4, GetSpellInfo(603))*0.001) < GS.SpellCDDuration(115356, nil))) and (not IsPlayerMoving() or GS.Aura("player", 172106)) and ((GS.Aura("player", 53817) and not GS.Aura("player", 114051)) or GS.Aura("player", 16188)) then GS.Cast("target", 403, false, false, false, "SpellToInterrupt") return end -- lightning bolt
				if GetTotemInfo(1) then
					local _, _, start, duration = GetTotemInfo(1)
					local totemTimeRemaining = duration-(GetTime()-start)
					if GS.SIR(3599) and totemTimeRemaining <= 20 and select(2, GetTotemInfo(1)) ~= "Fire Elemental Totem" and GS.SpellCDDuration(152255, nil) < 35 then GS.Cast("target", 3599, false, false, false, "SpellToInterrupt") return end
				end
			end
		end
	end

	function GS.SHAMAN3() -- resto todo: chain heal, throttle healing wave, change throttles to new caster system (warlock affliction)
		-- base mana is 32k
		-- mana regen = select(2, GetPowerRegen())

		if not GS.Aura("player", 52127) and not IsMounted() then GS.Cast("target", 52127, false, false, false, "SpellToInterrupt") return end -- water shield
		
		-- keep earth shield on one tank *1.2
		-- UnitGroupRolesAssigned() "TANK"
		if GS.SIR(974) and not GS.IsCAOCH() and UnitExists("focus") and not GS.Aura("focus", 974, "", "PLAYER") then GS.Cast("focus", 974, false, false, false, "SpellToInterrupt") return end
		if GS.Combat() then GS.MultiHoT("Riptide") end
		if GS.Combat() and not GS.IsCAOCH() then

			if GS.ValidTarget() and GSR.Interrupt then GS.Interrupt() end

			-- riptide on cooldown
			-- mana cost = 2332.8
			-- initial healing = GetSpellBonusHealing()*1.8
			-- over time: GetSpellBonusHealing()*.39162380602498*6
			-- total healing = GetSpellBonusHealing()*1.8+GetSpellBonusHealing()*.39162380602498*6 doesn't take into account haste dot
			if GS.SIR(61295) and not GS.Aura("player", 118473) then -- riptide on cooldown
				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(61295, v.Player, interruptCasting) and not GS.Aura(v.Player, 61295, "", "PLAYER") and v.Stats.HealthRemaining >= GS.ShamanHealing("Riptide") then GS.Cast(v.Player, 61295, false, false, false, "SpellToInterrupt") return end
				end
				if GS.SCA(61295, "player", interruptCasting) and not GS.Aura("player", 61295, "", "PLAYER") and (GS.Health("player", true, percenthealth)-GS.Health("player", maxhealth, percenthealth)) >= GS.ShamanHealing("Riptide") then GS.Cast("player", 61295, false, false, false, "SpellToInterrupt") return end
				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(61295, v.Player, interruptCasting) and not GS.Aura(v.Player, 61295, "", "PLAYER") and v.Stats.HealthRemaining >= GS.ShamanHealing("Riptide") then GS.Cast(v.Player, 61295, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(61295, v.Player, interruptCasting) and not GS.Aura(v.Player, 61295, "", "PLAYER") and v.Stats.HealthRemaining >= GS.ShamanHealing("Riptide") then GS.Cast(v.Player, 61295, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Players ~= "DPS" then
						if GS.SCA(61295, v.Player, interruptCasting) and not GS.Aura(v.Player, 61295, "", "PLAYER") and v.Stats.HealthRemaining >= GS.ShamanHealing("Riptide") then GS.Cast(v.Player, 61295, false, false, false, "SpellToInterrupt") return end
					end
				end
			end

			-- healing rain if worth it
			-- mana cost = 6912
			-- Radius: 10 yards
			-- initial healing = GetSpellBonusHealing()*.42836149889787
			-- over time: GetSpellBonusHealing()*.42836149889787*5
			-- total healing = GetSpellBonusHealing()*.42836149889787*5+GetSpellBonusHealing()*.42836149889787 doesn't take into account haste dot
			if GS.SIR(73920) and IsShiftKeyDown() and UnitExists("mouseover") then GS.Cast("mouseover", 73920, false, false, false, "SpellToInterrupt") return end

			-- chain heal on riptided targets
			-- mana cost = 8960
			-- radius: 10?
			-- initial healing = 2.1193975018369*GetSpellBonusHealing()*1.5
			-- bounce = 2.1193975018369*GetSpellBonusHealing()*(#ofbounces*.9)

			if not IsPlayerMoving() and not GetTotemInfo(3) and GS.SIR(5394) and not GS.IsCAOCH() and (not GS.PlayerHasTalent(7, 1) or (GS.SIR(5394) and GS.SIR(157153) or (GS.SpellCDDuration(157153, nil) > 0 and not GetTotemInfo(3)))) then GS.Cast("target", 5394, false, false, false, "SpellToInterrupt") return end
			
			-- cloud burst (me)
			if GS.PlayerHasTalent(7, 1) and not GetTotemInfo(3) and not IsPlayerMoving() and GS.SIR(157153) and not GS.IsCAOCH() and (GS.SpellCDDuration(5394, nil) > 0 and not GetTotemInfo(3)) then GS.Cast("target", 157153, false, false, false, "SpellToInterrupt") return end -- cloudburst totem

			-- healing surge with tidal waves on tanks
			-- mana cost = 6624
			-- healing = 
			if GS.CDs and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 79206)) and GS.Aura("player", 53390) and GS.SIR(8004) then
				if #GS.Players[tanksIndex].Players > 0 then
					for k,v in ipairs(GS.Players[tanksIndex].Players) do
						if GS.SCA(8004, v.Player, interruptCasting) and v.Stats.HealthRemaining >= (GS.ShamanHealing("Healing Surge")*(1+GetCritChance()*.01+.3)) then GS.Cast(v.Player, 8004, false, false, false, "SpellToInterrupt") return end
					end
				end
			end

			-- unleash life to empower chain heals, riptides, or healing surges
			if GS.SIR(73685) and not GS.IsCAOCH() then
				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(73685, v.Player, interruptCasting) and v.Stats.HealthRemaining >= GS.ShamanHealing("Unleash Life") then GS.Cast(v.Player, 73685, false, false, false, "SpellToInterrupt") return end
				end
				if GS.SCA(73685, "player", interruptCasting) and (GS.Health("player", true, percenthealth)-GS.Health("player", maxhealth, percenthealth)) >= GS.ShamanHealing("Unleash Life") then GS.Cast("player", 73685, false, false, false, "SpellToInterrupt") return end
				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(73685, v.Player, interruptCasting) and v.Stats.HealthRemaining >= GS.ShamanHealing("Unleash Life") then GS.Cast(v.Player, 73685, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(73685, v.Player, interruptCasting) and v.Stats.HealthRemaining >= GS.ShamanHealing("Unleash Life") then GS.Cast(v.Player, 73685, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Players ~= "DPS" then
						if GS.SCA(73685, v.Player, interruptCasting) and v.Stats.HealthRemaining >= GS.ShamanHealing("Unleash Life") then GS.Cast(v.Player, 73685, false, false, false, "SpellToInterrupt") return end 
					end
				end
			end

			-- healing wave
			if GS.SIR(77472) and not GS.IsCAOCH() and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 79206)) then
				for k,v in ipairs(GS.Players[tanksIndex].Players) do
					if #GS.Players[dpsIndex].Players > 0 and GS.Players[dpsIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthRemaining ~= 0 then
						GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt")
						return
					end
				end
				for k,v in ipairs(GS.Players[dpsIndex].Players) do
					if #GS.Players[healersIndex].Players > 0 and GS.Players[healersIndex].Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					elseif #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthRemaining ~= 0 then GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players[healersIndex].Players) do
					if #GS.Players > 3 and GS.Players[1].Stats.HealthPercent < v.Stats.HealthPercent then
						break
					end
					if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthRemaining ~= 0 then GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt") return end
				end
				for k,v in ipairs(GS.Players) do
					if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Players ~= "DPS" then
						if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthRemaining ~= 0 then GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt") return end
					end
				end
			end

			-- cooldowns
			return
		end

		if GS.SIR(77472) and not GS.IsCAOCH() and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 79206)) then
			for k,v in ipairs(GS.Players[tanksIndex].Players) do
				if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthPercent ~= 100 and v.Stats.HealthPercent ~= 0 then
					GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt")
					return
				end
			end
			for k,v in ipairs(GS.Players[dpsIndex].Players) do
				if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthPercent ~= 100 and v.Stats.HealthPercent ~= 0 then
					GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt")
					return
				end
			end
			for k,v in ipairs(GS.Players[healersIndex].Players) do
				if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthPercent ~= 100 and v.Stats.HealthPercent ~= 0 then
					GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt")
					return
				end
			end
			for k,v in ipairs(GS.Players) do
				if v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
					if GS.SCA(77472, v.Player, interruptCasting) and v.Stats.HealthPercent ~= 100 and v.Stats.HealthPercent ~= 0 then
						GS.Cast(v.Player, 77472, false, false, false, "SpellToInterrupt")
						return
					end
				end
			end
		end
	end

	function GS.MAGE1() -- arcane -- todo: add prismatic crystal support, rune of power, mirror image, cold snap, cooldowns, nether tempest @mage
		if GS.SIR(1459) and not GS.IsCAOCH() and (not GetRaidBuffTrayAuraInfo(5) or not GetRaidBuffTrayAuraInfo(6)) and not IsMounted() then GS.Cast("player", 1459, false, false, false, "SpellToInterrupt") return end -- arcane brilliance

		if GS.Combat() then
			local arcaneStacks = select(4, GS.Aura("player", 36032)) or 0
			-- actions+=/rune_of_power,if=buff.rune_of_power.remains<cast_time
			-- actions+=/mirror_image
			-- actions+=/cold_snap,if=buff.presence_of_mind.down&cooldown.presence_of_mind.remains>75

			-- actions+=/call_action_list,name=init_crystal,if=talent.prismatic_crystal.enabled&cooldown.prismatic_crystal.up
			-- actions+=/call_action_list,name=crystal_sequence,if=talent.prismatic_crystal.enabled&pet.prismatic_crystal.active
			if GS.ValidTarget() then
				if GSR.Thok and UnitChannelInfo("player") and ThokThrottle > GetTime() and ThokThrottle-GetTime() <= (1.5/(1+GetHaste()*.01)) then SpellStopCasting() end
				if UnitChannelInfo("player") == "Evocation" and GS.PM() > 92 then SpellStopCasting() end

				if GS.TargetCount(8) >= 4 then -- aoe
					if GS.CDs then
						if GS.SIR(12042) then GS.Cast("target", 12042, false, false, false, "SpellToInterrupt") return end
						-- actions.cooldowns+=/blood_fury
						-- actions.cooldowns+=/berserking
						-- actions.cooldowns+=/arcane_torrent
						-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.arcane_power.up&(!talent.prismatic_crystal.enabled|pet.prismatic_crystal.active)
					end

					-- actions.aoe+=/nether_tempest,cycle_targets=1,if=buff.arcane_charge.stack=4&(active_dot.nether_tempest=0|(ticking&remains<3.6))
					if GS.PlayerHasTalent(5, 3) and GS.SCA(157980, "target", interruptCasting) then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- supernova less mana
					if GS.SIR(44425) and arcaneStacks == 4 then GS.Cast("target", 44425, false, false, false, "SpellToInterrupt") return end -- arcane barrage for aoe
					if GS.PlayerHasTalent(7, 3) and arcaneStacks < 4 and GS.SIR(153626) and GS.IsFacing("player", "target") then GS.Cast("target", 153626, false, false, false, "SpellToInterrupt") return end -- arcane orb for stacks
					if GS.SIR(120) and GS.PlayerHasGlyph(115705) and GS.IsFacing("player", "target") and GS.Distance("target", nil) < 12+UnitCombatReach("target") then GS.Cast("target", 120, false, false, false, "SpellToInterrupt") return end -- cone of cold glyph
					if GS.SIR(1449) and GS.PlayerCount(8) >= 4 then GS.Cast("target", 1449, false, false, false, "SpellToInterrupt") return end -- arcane explosion
				end

				if GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < (GS.PM()*0.35*(1/(1+GetHaste()*.01))) or GS.SpellCDDuration(12051, nil) <= ((GS.PM()-30)*.3*(1/(1+GetHaste()*.01))) or (GS.Aura("player", 12042) and GS.SpellCDDuration(12051, nil) <= ((GS.PM()-30)*.4*(1/(1+GetHaste()*.01)))) then
					if GS.CDs and GS.UnitIsBoss("target") then
						if GS.SIR(12042) and not GS.IsCAOCH() then GS.Cast("target", 12042, false, false, false, "SpellToInterrupt") return end
						-- actions.cooldowns+=/blood_fury
						-- actions.cooldowns+=/berserking
						-- actions.cooldowns+=/arcane_torrent
						-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.arcane_power.up&(!talent.prismatic_crystal.enabled|pet.prismatic_crystal.active)
					end

					if GS.SCA(5143, "target", interruptCasting) and GS.AuraStacks("player", 79683, 3) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles dump
					if GS.SCA(5143, "target", interruptCasting) and GS.Aura("player", 166872) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) and GS.AuraRemaining("player", 166872, select(4, GetSpellInfo(30451))*0.001) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles 4piece
					if GS.PlayerHasTalent(5, 3) and GS.SCA(157980, "target", interruptCasting) and ((GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 8) or GetSpellCharges(157980) == 2) then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- supernova
					-- if GS.PlayerHasTalent(5, 1) and GS.SIR(114923) and currentTarget ~= prismaticCrystal and arcaneStacks == 4 and (not GS.Aura("target", 114923, "", "PLAYER") or GS.AuraRemaining("target", 114923, 3.6)) then GS.Cast("target", 114923, false, false, false, "SpellToInterrupt") return end -- nether tempest -- todo: implement multidot nether tempest @mage
					if GS.PlayerHasTalent(7, 3) and arcaneStacks < 4 and GS.SIR(153626) and not GS.IsCAOCH() and GS.IsFacing("player", "target") then GS.Cast("target", 153626, false, false, false, "SpellToInterrupt") return end -- arcane orb
					-- if GS.PlayerHasTalent(5, 3) and currentTarget == prismaticCrystal and GS.SCA(157980, "target", interruptCasting) then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- supernova if crystal is target
					if GS.SIR(12043) and not GS.IsCAOCH() and GS.PM() > 96  then GS.Cast("target", 12043, false, false, false, "SpellToInterrupt") return end -- presence of mind high mana
					if GS.SCA(30451, "target",  intteruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 108839)) and arcaneStacks == 4 and GS.PM() > 93 then GS.Cast("target", 30451, false, false, false, "SpellToInterrupt") return end -- arcane blast high mana
					if arcaneStacks == 4 and GS.SCA(5143, "target", interruptCasting) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles
					if GS.PlayerHasTalent(5, 3) and GS.SCA(157980, "target", interruptCasting) and GS.PM() < 96 then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- supernova less mana
					if 90 - GS.SpellCDDuration(12051, nil) < 5 then phase[1] = "conserve" return end
					if GS.SIR(12051) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > 5.5) and not GS.IsCAOCH() and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 10 and GS.PM() < 50 then GS.Cast("player", 12051, false, false, false, "SpellToInterrupt") return end -- evocation
					if GS.SIR(12043) and not GS.IsCAOCH() then GS.Cast("target", 12043, false, false, false, "SpellToInterrupt") return end -- presence of mind
					if GS.SCA(30451, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 108839)) then GS.Cast("target", 30451, false, false, false, "SpellToInterrupt") return end -- arcane blast
					return
				end

				if GS.CDs and GS.UnitIsBoss("target") and ((GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 30) or (arcaneStacks == 4 and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152087, nil) > 15))) then
					if GS.SIR(12042) and not GS.IsCAOCH() then GS.Cast("target", 12042, false, false, false, "SpellToInterrupt") return end
					-- actions.cooldowns+=/blood_fury
					-- actions.cooldowns+=/berserking
					-- actions.cooldowns+=/arcane_torrent
					-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.arcane_power.up&(!talent.prismatic_crystal.enabled|pet.prismatic_crystal.active)
				end
				if GS.SCA(5143, "target", interruptCasting) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) and (GS.AuraStacks("player", 79683, 3) or (GS.PlayerHasTalent(7, 1) and GS.Aura("player", 12042) and GS.AuraRemaining("player", 12042, select(4, GetSpellInfo(30451))*0.001))) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles dump or extend arcane pwoer
				if GS.SCA(5143, "target", interruptCasting) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) and GS.Aura("player", 166872) and GS.AuraRemaining("player", 166872, select(4, GetSpellInfo(30451))*0.001) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles 4piece
				-- if GS.PlayerHasTalent(5, 1) and GS.SIR(114923) and currentTarget ~= prismaticCrystal and arcaneStacks == 4 and (not GS.Aura("target", 114923, "", "PLAYER") or GS.AuraRemaining("target", 114923, 3.6)) then GS.Cast("target", 114923, false, false, false, "SpellToInterrupt") return end -- nether tempest
				if GS.PlayerHasTalent(5, 3) and GS.SCA(157980, "target", interruptCasting) and ((GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 8) or (GetSpellCharges(157980) == 2 and (GS.Aura("player", 12042) or not GS.SIR(12042)) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152087, nil) > 8))) then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- supernova dump cooldown
				if GS.PlayerHasTalent(7, 3) and arcaneStacks < 2 and GS.SIR(153626) and GS.IsFacing("player", "target") then GS.Cast("target", 153626, false, false, false, "SpellToInterrupt") return end -- arcane orb
				if GS.SIR(12043) and GS.PM() > 96 then GS.Cast("target", 12043, false, false, false, "SpellToInterrupt") return end -- presence of mind high mana
				if GS.SCA(30451, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 108839)) and GS.PM() > 93 and arcaneStacks == 4 then GS.Cast("target", 30451, false, false, false, "SpellToInterrupt") return end -- arcane blast high mana				
				if GS.SCA(5143, "target", interruptCasting) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) and arcaneStacks == 4 and (not GS.PlayerHasTalent(7, 1) or GS.SpellCDDuration(12042, nil) > (10*(1/(1+GetHaste()*.01)))) then GS.Cast("target", 5143, false, false, false, "SpellToInterrupt") return end -- arcane missiles dump before arcane power
				if GS.PlayerHasTalent(5, 3) and GS.SCA(157980) and GS.PM() < 96 and (not GS.AuraStacks("player", 79683, 2) or arcaneStacks == 4) and (GS.Aura("player", 12042) or (GetSpellCharges(157980) == 1 and GS.SpellCDDuration(12042, nil) > 25)) and (not GS.PlayerHasTalent(7, 2) or UnitName("target") == "Prismatic Crystal" or (GetSpellCharges(157980) == 1 and GS.SpellCDDuration(152087, nil) > 33)) then GS.Cast("target", 157980, false, false, false, "SpellToInterrupt") return end -- super nova
				-- actions.conserve+=/nether_tempest,cycle_targets=1,if=target!=prismatic_crystal&buff.arcane_charge.stack=4&(active_dot.nether_tempest=0|(ticking&remains<(10-3*talent.arcane_orb.enabled)*spell_haste))
				if GS.SCA(44425, "target", interruptCasting) and arcaneStacks == 4 then GS.Cast("target", 44425, false, false, false, "SpellToInterrupt") return end -- arcane barrage to get rid of stacks
				if GS.SIR(12043) and arcaneStacks < 2 then GS.Cast("target", 12043, false, false, false, "SpellToInterrupt") return end -- presence of mind less then two stacks
				if IsPlayerMoving() and not GS.Aura("player", 172106) and not GS.Aura("player", 108839) then
					if GS.SCA(44425, "target", interruptCasting) then GS.Cast("target", 44425, false, false, false, "SpellToInterrupt") return end -- arcane barrage moving
				else
					if GS.SCA(30451, "target", interruptCasting) then GS.Cast("target", 30451, false, false, false, "SpellToInterrupt") return end -- arcane blast
				end

			end
		end
	end

	function GS.MAGE2() -- fire
		-- actions.precombat=flask,type=greater_draenic_intellect_flask
		-- actions.precombat+=/food,type=blackrock_barbecue
		-- actions.precombat+=/arcane_brilliance
		-- actions.precombat+=/snapshot_stats
		-- actions.precombat+=/rune_of_power
		-- actions.precombat+=/mirror_image
		-- actions.precombat+=/potion,name=draenic_intellect
		-- actions.precombat+=/pyroblast

		-- # Executed every time the actor is available.

		-- actions=counterspell,if=target.debuff.casting.react
		-- actions+=/blink,if=movement.distance>10
		-- actions+=/blazing_speed,if=movement.remains>0
		-- actions+=/time_warp,if=target.health.pct<25|time>5
		-- actions+=/ice_floes,if=buff.ice_floes.down&(raid_event.movement.distance>0|raid_event.movement.in<action.fireball.cast_time)
		-- actions+=/rune_of_power,if=buff.rune_of_power.remains<cast_time
		-- actions+=/call_action_list,name=combust_sequence,if=pyro_chain
		-- actions+=/call_action_list,name=crystal_sequence,if=talent.prismatic_crystal.enabled&pet.prismatic_crystal.active
		-- actions+=/call_action_list,name=init_combust,if=!pyro_chain
		-- # Utilize level 90 active talents while avoiding pyro munching
		-- actions+=/rune_of_power,if=buff.rune_of_power.remains<action.fireball.execute_time+gcd.max&!(buff.heating_up.up&action.fireball.in_flight)
		-- actions+=/mirror_image,if=!(buff.heating_up.up&action.fireball.in_flight)
		-- actions+=/call_action_list,name=aoe,if=active_enemies>=4
		-- actions+=/call_action_list,name=single_target

		-- # Action list while Prismatic Crystal is up
		-- # Spread Combustion from PC; "active_enemies+1" because PC is not counted
		-- actions.crystal_sequence=inferno_blast,cycle_targets=1,if=dot.combustion.ticking&active_dot.combustion<active_enemies+1
		-- # Use pyros before PC's expiration
		-- actions.crystal_sequence+=/pyroblast,if=execute_time=gcd.max&pet.prismatic_crystal.remains<gcd.max+travel_time&pet.prismatic_crystal.remains>travel_time
		-- actions.crystal_sequence+=/call_action_list,name=single_target

		-- # Combustion sequence initialization
		-- # This sequence lists the requirements for preparing a Combustion combo with each talent choice
		-- # Meteor Combustion
		-- actions.init_combust=start_pyro_chain,if=talent.meteor.enabled&cooldown.meteor.up&((cooldown.combustion.remains<gcd.max*3&buff.pyroblast.up&(buff.heating_up.up^action.fireball.in_flight))|(buff.pyromaniac.up&(cooldown.combustion.remains<ceil(buff.pyromaniac.remains%gcd.max)*gcd.max)))
		-- # Prismatic Crystal Combustion
		-- actions.init_combust+=/start_pyro_chain,if=talent.prismatic_crystal.enabled&cooldown.prismatic_crystal.up&((cooldown.combustion.remains<gcd.max*2&buff.pyroblast.up&(buff.heating_up.up^action.fireball.in_flight))|(buff.pyromaniac.up&(cooldown.combustion.remains<ceil(buff.pyromaniac.remains%gcd.max)*gcd.max)))
		-- actions.init_combust+=/start_pyro_chain,if=talent.prismatic_crystal.enabled&!glyph.combustion.enabled&cooldown.prismatic_crystal.remains>20&((cooldown.combustion.remains<gcd.max*2&buff.pyroblast.up&buff.heating_up.up&action.fireball.in_flight)|(buff.pyromaniac.up&(cooldown.combustion.remains<ceil(buff.pyromaniac.remains%gcd.max)*gcd.max)))
		-- # Kindling or Level 90 Combustion
		-- actions.init_combust+=/start_pyro_chain,if=!talent.prismatic_crystal.enabled&!talent.meteor.enabled&((cooldown.combustion.remains<gcd.max*4&buff.pyroblast.up&buff.heating_up.up&action.fireball.in_flight)|(buff.pyromaniac.up&cooldown.combustion.remains<ceil(buff.pyromaniac.remains%gcd.max)*(gcd.max+talent.kindling.enabled)))

		-- # Combustion Sequence
		-- actions.combust_sequence=stop_pyro_chain,if=cooldown.combustion.duration-cooldown.combustion.remains<15
		-- actions.combust_sequence+=/prismatic_crystal
		-- actions.combust_sequence+=/blood_fury
		-- actions.combust_sequence+=/berserking
		-- actions.combust_sequence+=/arcane_torrent
		-- actions.combust_sequence+=/potion,name=draenic_intellect
		-- actions.combust_sequence+=/meteor
		-- actions.combust_sequence+=/pyroblast,if=set_bonus.tier17_4pc&buff.pyromaniac.up
		-- actions.combust_sequence+=/inferno_blast,if=set_bonus.tier16_4pc_caster&(buff.pyroblast.up^buff.heating_up.up)
		-- actions.combust_sequence+=/fireball,if=!dot.ignite.ticking&!in_flight
		-- actions.combust_sequence+=/pyroblast,if=buff.pyroblast.up
		-- # Meteor Combustions can run out of Pyro procs before impact. Use IB to delay Combustion
		-- actions.combust_sequence+=/inferno_blast,if=talent.meteor.enabled&cooldown.meteor.duration-cooldown.meteor.remains<gcd.max*3
		-- actions.combust_sequence+=/combustion

		-- # Active talents usage
		-- actions.active_talents=meteor,if=active_enemies>=5|(glyph.combustion.enabled&(!talent.incanters_flow.enabled|buff.incanters_flow.stack+incanters_flow_dir>=4)&cooldown.meteor.duration-cooldown.combustion.remains<10)
		-- actions.active_talents+=/call_action_list,name=living_bomb,if=talent.living_bomb.enabled
		-- actions.active_talents+=/blast_wave,if=(!talent.incanters_flow.enabled|buff.incanters_flow.stack>=4)&(time_to_die<10|!talent.prismatic_crystal.enabled|(charges=1&cooldown.prismatic_crystal.remains>recharge_time)|charges=2|current_target=prismatic_crystal)

		-- # Living Bomb application
		-- actions.living_bomb=inferno_blast,cycle_targets=1,if=dot.living_bomb.ticking&active_dot.living_bomb<active_enemies
		-- actions.living_bomb+=/living_bomb,cycle_targets=1,if=target!=prismatic_crystal&(active_dot.living_bomb=0|(ticking&active_dot.living_bomb=1))&(((!talent.incanters_flow.enabled|incanters_flow_dir<0|buff.incanters_flow.stack=5)&remains<3.6)|((incanters_flow_dir>0|buff.incanters_flow.stack=1)&remains<gcd.max))&target.time_to_die>remains+12

		-- # AoE sequence
		-- actions.aoe=inferno_blast,cycle_targets=1,if=(dot.combustion.ticking&active_dot.combustion<active_enemies)|(dot.pyroblast.ticking&active_dot.pyroblast<active_enemies)
		-- actions.aoe+=/call_action_list,name=active_talents
		-- actions.aoe+=/pyroblast,if=buff.pyroblast.react|buff.pyromaniac.react
		-- actions.aoe+=/pyroblast,if=active_dot.pyroblast=0&!in_flight
		-- actions.aoe+=/cold_snap,if=glyph.dragons_breath.enabled&!cooldown.dragons_breath.up
		-- actions.aoe+=/dragons_breath,if=glyph.dragons_breath.enabled
		-- actions.aoe+=/flamestrike,if=mana.pct>10&remains<2.4

		-- # Single target sequence
		-- actions.single_target=inferno_blast,if=(dot.combustion.ticking&active_dot.combustion<active_enemies)|(dot.living_bomb.ticking&active_dot.living_bomb<active_enemies)
		-- # Use Pyro procs before they run out
		-- actions.single_target+=/pyroblast,if=buff.pyroblast.up&buff.pyroblast.remains<action.fireball.execute_time
		-- actions.single_target+=/pyroblast,if=set_bonus.tier16_2pc_caster&buff.pyroblast.up&buff.potent_flames.up&buff.potent_flames.remains<gcd.max
		-- actions.single_target+=/pyroblast,if=set_bonus.tier17_4pc&buff.pyromaniac.react
		-- # Pyro camp during regular sequence; Do not use Pyro procs without HU and first using fireball
		-- actions.single_target+=/pyroblast,if=buff.pyroblast.up&buff.heating_up.up&action.fireball.in_flight
		-- actions.single_target+=/inferno_blast,if=buff.pyroblast.down&buff.heating_up.up
		-- actions.single_target+=/call_action_list,name=active_talents
		-- actions.single_target+=/inferno_blast,if=buff.pyroblast.up&buff.heating_up.down&!action.fireball.in_flight
		-- actions.single_target+=/fireball
		-- actions.single_target+=/scorch,moving=1
	end

	local frostSwitch
	function GS.MAGE3() -- frost -- todo: implement @mage
		if GS.SIR(1459) and not GS.IsCAOCH() and (not GetRaidBuffTrayAuraInfo(5) or not GetRaidBuffTrayAuraInfo(6)) and not IsMounted() then GS.Cast("player", 1459, false, false, false, "SpellToInterrupt") return end -- arcane brilliance
		-- actions.precombat+=/water_elemental
		if GS.Combat() then
			local iceNovaRecharge = 25-(GetTime()-select(3, GetSpellCharges(157997)))
			if GS.ValidTarget() then
				-- // frost bolt = 116
				-- // frostfire bolt = 44614
				-- // ice lance = 30455
				-- // fingers of frost = 44544
				-- // brain freeze = 57761
				-- // frozen orb = 84714

				if GSR.Thok and UnitChannelInfo("player") and ThokThrottle > GetTime() and ThokThrottle-GetTime() <= (1.5/(1+GetHaste()*.01)) then SpellStopCasting() end
				if UnitChannelInfo("player") == "Blizzard" and GS.SpellCDDuration(61304, nil) == 0 and (GS.SpellCDDuration(84714, nil) == 0 or GS.PlayerHasTalent(5, 1) and GS.AuraStacks("player", 44544, 2)) then SpellStopCasting() end
				if GSR.Interrupt then GS.Interrupt() end
				frostSwitch = false
				if GS.CastDebug.name == "Water Jet" or GS.Aura("target", 135029, "", "PLAYER") then
					if GS.CastDebug.name == "Water Jet" and GS.SCA(116, "target", interruptCasting) then GS.Cast("target", 116, false, false, false, "SpellToInterrupt") return end -- frostbolt immediately
					if GS.SCA(30455, "target", interruptCasting) and GS.AuraStacks("player", 44544, 2) and frostBoltInFlight then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end -- ice lance dump before frost bolt lands
					if GS.SCA(116, "target", interruptCasting) and (select(7, GS.Aura("target", 135029, "", "PLAYER"))-GetTime()) > (select(4, GetSpellInfo(116))*0.001)+GS.Distance("target", nil)/28 then GS.Cast("target", 116, false, false, false, "SpellToInterrupt") return end -- frostbolt if you can
					if GS.CastDebug.name == "Frostbolt" and GS.SCA(30455, "target", interruptCasting) then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end -- ice lance after frostbolt
					frostSwitch = true
				end
				if not frostSwitch then
					if GS.CDs and GS.PlayerHasTalent(6, 1) and GS.SIR(55342) then GS.Cast("target", 55342, nil) return end -- mirror image
					-- actions+=/rune_of_power,if=buff.rune_of_power.remains<cast_time
					-- actions+=/rune_of_power,if=(cooldown.icy_veins.remains<gcd.max&buff.rune_of_power.remains<20)|(cooldown.prismatic_crystal.remains<gcd.max&buff.rune_of_power.remains<10)
					if GS.CDs and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 24 then
						if GS.SIR(12472) then GS.Cast("target", 12472, false, false, false, "SpellToInterrupt") return end -- icy veins
						if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("player", 33702, nil) return end
						if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end
						-- actions.cooldowns+=/arcane_torrent
						-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.bloodlust.up|buff.icy_veins.up
					end
					if GS.SCA(135029, "target", interruptCasting) and (GetTime()-GS.CombatStart) < 1 and GS.TargetCount(8) < 4 and not GS.PlayerHasTalent(7, 2) and not GS.PlayerHasTalent(5, 3) then GS.Cast("target", 135029, false, false, false, "SpellToInterrupt") return end -- water jet on pull
					if GS.CDs and GS.PlayerHasTalent(7, 2) and (GS.SpellCDDuration(152087, nil) <= (1.5/(1+GetHaste()*.01)) or GS.SpellCDDuration(152087, nil) > 80) then
						-- actions.crystal_sequence=frost_bomb,if=active_enemies=1&current_target!=prismatic_crystal&remains<10
						if GS.SIR(84714) and not GS.IsCAOCH() then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 84714, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
						if GS.CDs then
							if GS.SIR(12472) then GS.Cast("target", 12472, false, false, false, "SpellToInterrupt") return end -- icy veins
							if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("player", 33702, nil) return end
							if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end
							-- actions.cooldowns+=/arcane_torrent
							-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.bloodlust.up|buff.icy_veins.up
						end
						if GS.SIR(152087) then
							local x,y,z = GS.SmartAoE(40, 8, true)
							GS.Cast(nil, 152087, x, y, z, "SpellToInterrupt")
							return
						end
						-- actions.crystal_sequence+=/frost_bomb,if=talent.prismatic_crystal.enabled&current_target=prismatic_crystal&active_enemies>1&!ticking
						if GS.SCA(30455, "target", interruptCasting) and (GS.AuraStacks("player", 44544, 2) or GS.Aura("player", 44544) and GS.SpellCDDuration(84714, nil) > 50) then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end -- ice lance at 2 or 1 and frozen orb
						if GS.PlayerHasTalent(5, 3) and GS.SCA(157997, "target", interruptCasting) and GetSpellCharges(157997) == 2 then GS.Cast("target", 157997, false, false, false, "SpellToInterrupt") return end -- ice nova two charges
						if GS.SCA(44614, "target", interruptCasting) and GS.Aura("player", 57761) then GS.Cast("target", 44614, false, false, false, "SpellToInterrupt") return end -- frost fire bolt brain freeze
						if GS.SCA(30455, "target", interruptCasting) and GS.Aura("player", 44544) then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end -- ice lance with fingers of frost
						if GS.PlayerHasTalent(5, 3) and GS.SCA(157997, "target", interruptCasting) then GS.Cast("target", 157997, false, false, false, "SpellToInterrupt") return end -- ice nova
						if GS.TargetCount(8) >= 4 and GS.SIR(10) and not GS.IsCAOCH() and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then -- blizzard
							local x,y,z = GS.SmartAoE(35, 8, true)
							GS.Cast("target", 10, x, y, z, "SpellToInterrupt")
							return
						end
						if GS.SCA(116, "target", interruptCasting) then GS.Cast("target", 116, false, false, false, "SpellToInterrupt") return end -- frostbolt
						return
					end
					if GS.AoE and GS.TargetCount(8) >= 4 then
						if GS.CDs then
							if GS.SIR(12472) then GS.Cast("target", 12472, false, false, false, "SpellToInterrupt") return end -- icy veins
							if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("player", 33702, nil) return end
							if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end
							-- actions.cooldowns+=/arcane_torrent
							-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.bloodlust.up|buff.icy_veins.up
						end
						-- if GS.PlayerHasTalent(5, 1) and 
							-- actions.aoe+=/frost_bomb,if=remains<action.ice_lance.travel_time&(cooldown.frozen_orb.remains<gcd.max|buff.fingers_of_frost.react=2)
						if GS.SIR(84714) and not GS.IsCAOCH() then
							local rot = ObjectFacing("player")
							GS.Face("target")
							GS.Cast("target", 84714, false, false, false, "SpellToInterrupt")
							FaceDirection(rot)
							return
						end
						-- if GS.PlayerHasTalent(5, 1) and 
							-- actions.aoe+=/ice_lance,if=talent.frost_bomb.enabled&buff.fingers_of_frost.react&debuff.frost_bomb.up
						if GS.PlayerHasTalent(7, 3) and GS.SCA(153595, "target", interruptCasting) then GS.Cast("target", 153595, false, false, false, "SpellToInterrupt") return end -- comet storm
						if GS.PlayerHasTalent(5, 3) and GS.SCA(157997, "target", interruptCasting) then GS.Cast("target", 157997, false, false, false, "SpellToInterrupt") return end -- ice nova
						if GS.TargetCount(8) and GS.SIR(10) and not GS.IsCAOCH() and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then -- blizzard
							local x,y,z = GS.SmartAoE(35, 8, true)
							GS.Cast("target", 10, x, y, z, "SpellToInterrupt")
							return
						end
						return
					end
				end

				if GS.CDs and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152087, nil) > 15) then
					if GS.SIR(12472) then GS.Cast("target", 12472, false, false, false, "SpellToInterrupt") return end -- icy veins
					if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("player", 33702, nil) return end
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("player", 26297, nil) return end
					-- actions.cooldowns+=/arcane_torrent
					-- actions.cooldowns+=/potion,name=draenic_intellect,if=buff.bloodlust.up|buff.icy_veins.up
				end

				if GS.SCA(30455) and GS.Aura("player", 44544) and GS.AuraRemaining("player", 44544, select(4, GetSpellInfo(116))*0.001) then GS.Cast("target", 30455, nil) return end -- ice lance fingers of frost emergency
				if GS.SCA(44614) and GS.Aura("player", 57761) and GS.AuraRemaining("player", 57761, select(4, GetSpellInfo(116))*0.001) then GS.Cast("target", 44614, nil) return end -- frostfire bolt brain freeze emergency

				-- actions.single_target+=/frost_bomb,if=!talent.prismatic_crystal.enabled&cooldown.frozen_orb.remains<gcd.max&debuff.frost_bomb.remains<10
				if not GS.PlayerHasTalent(7, 2) and GS.SIR(84714) and not GS.AuraStacks("player", 44544, 2) and GS.SpellCDDuration(12472, nil) > 45 then -- frozen orb
					local rot = ObjectFacing("player")
					GS.Face("target")
					GS.Cast("target", 84714, false, false, false, "SpellToInterrupt")
					FaceDirection(rot)
					return
				end 
				-- actions.single_target+=/frost_bomb,if=remains<action.ice_lance.travel_time&(buff.fingers_of_frost.react=2|(buff.fingers_of_frost.react&(talent.thermal_void.enabled|buff.fingers_of_frost.remains<gcd.max*2)))
				if GS.PlayerHasTalent(5, 3) and GS.SCA(157997, "target", interruptCasting) and ((GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 10) or (GetSpellCharges(157997) == 2 and (not GS.PlayerHasTalent(7, 2) or not GS.SIR(152087)))) then GS.Cast("target", 157997, false, false, false, "SpellToInterrupt") return end -- ice nova if time to death or charges == 2 and prismatic crystal not up
				if GS.SCA(30455) and (GS.AuraStacks("player", 44544, 2) or GS.Aura("player", 44544) and GS.SpellCDDuration(84714, nil) > 50) then GS.Cast("target", 30455, nil) return end -- ice lance fingers of frost
				if GS.PlayerHasTalent(7, 3) and GS.SCA(153595, "target", interruptCasting) then GS.Cast("target", 153595, false, false, false, "SpellToInterrupt") return end -- comet storm
				if GS.PlayerHasTalent(5, 3) and GS.SCA(157997, "target", interruptCasting) and (not GS.PlayerHasTalent(7, 2) or (GetSpellCharges(157997) == 1 and GS.SpellCDDuration(152087, nil) > iceNovaRecharge and GS.AuraStacks("player", 116267, 3))) and (GS.Aura("player", 12472) or (GetSpellCharges(157997) == 1 and GS.SpellCDDuration(12472, nil) > iceNovaRecharge)) then GS.Cast("target", 157997, false, false, false, "SpellToInterrupt") return end -- ice nova or some shit
				if GS.SCA(44614) and GS.Aura("player", 57761) then GS.Cast("target", 44614, nil) return end -- brain freeze frostfirebolt
				if GS.SCA(30455, "target", interruptCasting) and GS.TierBonus("t17") > 3 and GS.PlayerHasTalent(7, 1) and GS.PlayerHasTalent(6, 1) and GS.SpellCDDuration(84714, nil) > 50 then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end -- ice lance tier
				-- actions.single_target+=/ice_lance,if=talent.frost_bomb.enabled&buff.fingers_of_frost.react&debuff.frost_bomb.remains>travel_time&(!talent.thermal_void.enabled|cooldown.icy_veins.remains>8)
				if GS.SCA(116, "target", interruptCasting) and GS.TierBonus("t17") > 1 and GS.Aura("player", 166869) and not (GS.PlayerHasTalent(7, 1) and GS.Aura("player", 12472 and GS.AuraRemaining("player", 12472, 10))) then GS.Cast("target", 116, false, false, false, "SpellToInterrupt") return end -- frost bolt reduced cast time if icy veins can't be extended

				if not GS.PlayerHasTalent(5, 1) and GS.SCA(30455) and GS.Aura("player", 44544) and (not GS.PlayerHasTalent(7, 1) or GS.SpellCDDuration(12472, nil) > 8) then GS.Cast("target", 30455, nil) return end -- ice lance
				
				if GS.SpellCDDuration(135029, nil) <= (1.5/(1+GetHaste()*.01))*((GS.Aura("player", 44544) and select(4, GS.Aura("player", 44544)) or 0) + (GS.PlayerHasTalent(5, 1) and 1 or 0)) and GS.SpellCDDuration(84714, nil) < 50 then
					-- actions.init_water_jet=frost_bomb,if=remains<3.6
					if GS.SCA(30455, "target", interruptCasting) and GS.Aura("player", 44544) and GS.SpellCDDuration(135029, nil) == 0 then GS.Cast("target", 30455, false, false, false, "SpellToInterrupt") return end
					if GS.SCA(135029, "target", true) and GS.CastDebug.name == "Frostbolt" and (UnitCastingInfo("player") == "Frostbolt" and (select(6, UnitCastingInfo("player"))/1000-GetTime())+GS.Distance("target", nil)/28 <= .2+(select(4, GetSpellInfo(135029))*0.001)) then GS.Cast("target", 135029, false, false, false, "SpellToInterrupt") return end
					-- if GS.SCA(116, "target", interruptCasting) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 108839)) then GS.Cast("target", 116, false, false, false, "SpellToInterrupt") return end -- frostbolt
					-- return
				end

				if IsPlayerMoving() and not GS.Aura("player", 172106) and not GS.Aura("player", 108839) then
					if GS.SCA(30455, "target") then GS.Cast("target", 30455, nil) return end -- movign ice lance
				else
					if GS.SCA(116) then GS.Cast("target", 116, nil) return end -- frost bolt
				end
			end
		end
	end

	function GS.WARLOCK1() -- affliction -- todo: cooldowns @warlock
		if not IsMounted() and (not GetRaidBuffTrayAuraInfo(5) or not GetRaidBuffTrayAuraInfo(8)) then GS.Cast("player", 109773, false, false, false, "SpellToInterrupt") return end -- dark intent
		if GS.Combat() then
			GS.MultiDoT("Agony")
			GS.MultiDoT("Corruption")
			GS.MultiDoT("Unstable Affliction")

			for i = 1, #GS.Targets do
				if not GS.Warlock.UnstableAfflictionThrottle[UnitGUID(GS.Targets[i])] then GS.Warlock.UnstableAfflictionThrottle[UnitGUID(GS.Targets[i])] = 0 end
			end
			if GS.ValidTarget() then
				if GSR.Thok and UnitChannelInfo("player") and ThokThrottle > GetTime() and ThokThrottle-GetTime() <= (1.5/(1+GetHaste()*.01)) then SpellStopCasting() end

				if GS.CDs then
					-- actions=potion,name=draenic_intellect,if=buff.bloodlust.react|target.health.pct<=20
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") end
					if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("target", 33702, false, false, false, "SpellToInterrupt") end
					if GSR.Race == "BloodElf" and GS.SIR(28730) then GS.Cast("target", 28730, false, false, false, "SpellToInterrupt") end
					-- actions+=/mannoroths_fury
					
					if GS.SIR(113860) and not GS.Aura("player", 113860) and (not GS.PlayerHasTalent(6, 1) or (GetSpellCharges(113860) == 2 or GS.Trinket("int", "active") or GS.AuraStacks("player", 177081, 7) or GS.TTD[ObjectPointer("target")] and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] < 40)) then GS.Cast("target", 113860, false, false, false, "SpellToInterrupt") return end -- dark soul
					if GS.PlayerHasTalent(5, 2) then
						-- actions+=/service_pet,if=(target.time_to_die>120|target.time_to_die<20|(buff.dark_soul.remains&target.health.pct<20))
					end
					if not GS.PlayerHasTalent(7, 3) then
						if GS.CDs and GS.SIR(112927) and GS.TargetCount(10) < 5 then GS.Cast("target", 112927, false, false, false, "SpellToInterrupt") return end
						if GS.CDs and GS.SIR(1122) and GS.TargetCount(10) >= 5 then GS.Cast("target", 1122, false, false, false, "SpellToInterrupt") return end
					end
				end

				if GS.PlayerHasTalent(6, 2) and not GS.PlayerHasTalent(7, 2) and IsPlayerMoving() and not GS.Aura("player", 172106) and GS.SIR(137587) then GS.Cast("target", 137587, false, false, false, "SpellToInterrupt") end
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) then
					local x,y,z = GS.SmartAoE(40, 8, true, tableReturn)
					if GS.PlayerHasTalent(6, 2) and IsPlayerMoving() and not GS.Aura("player", 172106) and GS.SIR(137587) then GS.Cast("target", 137587, false, false, false, "SpellToInterrupt") end
					GS.Cast("target", 152108, x, y, z, "SpellToInterrupt")
					return
				end
				if not GS.PlayerHasTalent(7, 1) then
					if GS.SCA(48181, "target", true) and GS.Warlock.HauntThrottle == 0 and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 137587)) and (GS.AuraRemaining("target", 48181, 2.4+(select(4, GetSpellInfo(48181))*0.001)+(GS.Distance("target")/20), "", "PLAYER") or GS.PP() == 4) and (GS.Trinket("int", "active") or GS.AuraStacks("player", 177081, 7) or (GS.Aura("player", 113860) and (GS.UnitIsBoss("target") or not UnitExists("boss1"))) or (GS.PP() > 2 and (GS.UnitIsBoss("target") or not UnitExists("boss1"))) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.PP() * 14 <= GS.TTD[ObjectPointer("target")])) then GS.Cast("target", 48181, false, false, false, "Drain Soul") return end -- haunt
				else
					if GS.SIR(74434) and not GS.Aura("player", 74434) and GS.AuraRemaining("player", 157698, 9) then GS.Cast("target", 74434, false, false, false, "Drain Soul") return end -- soul burn
					

					if GS.SCA(48181, "target", true) and GS.Warlock.HauntThrottle == 0 and ((GS.Aura("player", 74434) and ((GS.AuraRemaining("player", 157698, 9) and GS.AuraRemaining("target", 48181, 2.4, "", "PLAYER")) or not GS.Aura("player", 157698)))) then GS.Cast("target", 48181, false, false, false, "Drain Soul") return end
					if GS.SCA(48181, "target", true) and GS.Warlock.HauntThrottle == 0 and not GS.AuraRemaining("player", 157698, 15) and (GS.AuraRemaining("target", 48181, 2.4+(select(4, GetSpellInfo(48181))*0.001)+(GS.Distance("target", nil)/20), "", "PLAYER") or GS.PP() == 4) and (GS.Trinket("int", "active") or GS.AuraStacks("player", 177081, 7) or GS.Aura("player", 113860) or GS.PP() > 2 or (GS.TTD[ObjectPointer("target")] and GS.UnitIsBoss("target") and GS.PP()*14 <= GS.TTD[ObjectPointer("target")])) then GS.Cast("target", 48181, false, false, false, "Drain Soul") return end
				end

				if GS.SIR(980) then -- agony cycle
					if GS.SCA(980, "target", true) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 16 and GS.AuraRemaining("target", 980, 7.2, "", "PLAYER") and (not GS.PlayerHasTalent(7, 2) or GS.AuraRemaining("target", 980, (GS.SpellCDDuration(152108, nil)+(select(4, GetSpellInfo(152108))*0.001)), "", "PLAYER")) then GS.Cast("target", 980, false, false, false, "Drain Soul") return
					elseif GS.AoE then
						for i = 1, #tNoObjectAgony do
							if GS.SCA(980, tNoObjectAgony[i], true) and GS.TTD[ObjectPointer(tNoObjectAgony[i])] and GS.TTD[ObjectPointer(tNoObjectAgony[i])] ~= math.huge and GS.TTD[ObjectPointer(tNoObjectAgony[i])] >= 16 and (not GS.PlayerHasTalent(7, 2)) then GS.Cast(tNoObjectAgony[i], 980, false, false, false, "Drain Soul") return end
						end
						for i = 1, #tAgony do
							if GS.SCA(980, tAgony[i], true) and GS.TTD[ObjectPointer(tAgony[i])] and GS.TTD[ObjectPointer(tAgony[i])] >= 16 and GS.AuraRemaining(tAgony[i], 980, 7.2, "", "PLAYER") and (not GS.PlayerHasTalent(7, 2) or GS.AuraRemaining(tAgony[i], 980, (GS.SpellCDDuration(152108, nil)+(select(4, GetSpellInfo(152108))*0.001)), "", "PLAYER")) then GS.Cast(tAgony[i], 980, false, false, false, "Drain Soul") return end
						end
					end
				end

				if GS.SIR(30108) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 137587)) then -- unstable affliction cycle
					if GS.SCA(30108, "target", true) and GS.Warlock.UnstableAfflictionThrottle[UnitGUID("target")] == 0 and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 10 and GS.AuraRemaining("target", 30108, 4.2, "", "PLAYER") then
						GS.Cast("target", 30108, false, false, false, "Drain Soul")
						return
					elseif GS.AoE then
						for i = 1, #tNoObjectUnstableAffliction do
							if GS.SCA(30108, tNoObjectUnstableAffliction[i], true) and GS.Warlock.UnstableAfflictionThrottle[UnitGUID(tNoObjectUnstableAffliction[i])] == 0 and GS.TTD[ObjectPointer(tNoObjectUnstableAffliction[i])] and GS.TTD[ObjectPointer(tNoObjectUnstableAffliction[i])] >= 10 then GS.Cast(tNoObjectUnstableAffliction[i], 30108, false, false, false, "Drain Soul") return end
						end
						for i = 1, #tUnstableAffliction do
							if GS.SCA(30108, tUnstableAffliction[i], true) and GS.Warlock.UnstableAfflictionThrottle[UnitGUID(tUnstableAffliction[i])] == 0 and GS.TTD[ObjectPointer(tUnstableAffliction[i])] and GS.TTD[ObjectPointer(tUnstableAffliction[i])] >= 10 and GS.AuraRemaining(tUnstableAffliction[i], 30108, 4.2, "", "PLAYER") then GS.Cast(tCorruption[i], 30108, false, false, false, "Drain Soul") return end
						end
					end
				end

				if GS.SIR(172) then -- corruption cycle
					if GS.SCA(172, "target", true) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 12 and GS.AuraRemaining("target", 146739, 5.4, "", "PLAYER") then GS.Cast("target", 172, false, false, false, "Drain Soul") return
					elseif GS.AoE then
						for i = 1, #tNoObjectCorruption do
							if GS.SCA(172, tNoObjectCorruption[i], true) and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] >= 12 then GS.Cast(tNoObjectCorruption[i], 172, false, false, false, "Drain Soul") return end
						end
						for i = 1, #tCorruption do
							if GS.SCA(172, tCorruption[i], true) and GS.TTD[ObjectPointer(tCorruption[i])] and GS.TTD[ObjectPointer(tCorruption[i])] >= 12 and GS.AuraRemaining(tCorruption[i], 146739, 5.4, "", "PLAYER") then GS.Cast(tCorruption[i], 172, false, false, false, "Drain Soul") return end
						end
					end
				end


				if GS.SIR(1454) and GS.PM() < 40 and not GS.Aura("player", 113860) then GS.Cast("target", 1454, false, false, false, "SpellToInterrupt") return end -- life tap below 40% mana
				if not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 137587) then
					if GS.SCA(103103, "target", true) and UnitChannelInfo("player") == "Drain Soul" and GS.AuraRemaining("target", 103103, 4/(1+GetHaste()*.01)/4) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 103103, false, false, false, "SpellToInterrupt") return end -- chaining
					if GS.SCA(103103, "target", interruptCasting) and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 103103, false, false, false, false) return end -- mind flay
				else
					if GS.AoE and GS.SIR(980) and GS.PM() > 50 then
						for i = 1, #tNoObjectAgony do
							if GS.SCA(980, tNoObjectAgony[i], interruptCasting) then GS.Cast(tNoObjectAgony[i], 980, false, false, false, "SpellToInterrupt") return end
						end
						local min, minTime = nil, math.huge
						for i = 1, #tAgony do
							if GS.SCA(980, tAgony[i], interruptCasting) then
								local _, _, _, _, _, _, agonyExpires = GS.Aura(tAgony[i], 980, "", "PLAYER")
								if agonyExpires-GetTime() < minTime then
									min = tAgony[i]
									minTime = agonyExpires-GetTime()
								end
							end
						end
						if min then GS.Cast(min, 980, false, false, false, "SpellToInterrupt") return end
					end
											-- if GS.AoE and GS.SIR(172) and GS.PM() > 50 then
											-- 	for i = 1, #tNoObjectCorruption do
											-- 		if GS.SCA(172, tNoObjectCorruption[i], interruptCasting) then GS.Cast(tNoObjectCorruption[i], 172, false, false, false, "SpellToInterrupt") return end
											-- 	end
											-- 	local min, minTime = nil, math.huge
											-- 	for i = 1, #tCorruption do
											-- 		if GS.SCA(172, tCorruption[i], interruptCasting) then
											-- 			local _, _, _, _, _, _, corruptionExpires = GS.Aura(tCorruption[i], 146739, "", "PLAYER")
											-- 			if corruptionExpires-GetTime() < minTime then
											-- 				min = tCorruption[i]
											-- 				minTime = corruptionExpires-GetTime()
											-- 			end
											-- 		end
											-- 	end
											-- 	if min then GS.Cast(min, 172, false, false, false, "SpellToInterrupt") return end
											-- end
				end
				if GS.SIR(1454) and GS.PoolCheck(980) and not GS.IsCAOCH() then GS.Cast("target", 1454, false, false, false, "SpellToInterrupt") return end -- life tap if nothing else is possible
			end
			return
		end
		table.wipe(GS.Warlock.UnstableAfflictionThrottle)
	end

	function GS.WARLOCK2() -- demonology -- todo: cooldowns, kj cunning @warlock
		if not IsMounted() and (not GetRaidBuffTrayAuraInfo(5) or not GetRaidBuffTrayAuraInfo(8)) then GS.Cast("player", 109773, false, false, false, "SpellToInterrupt") return end -- dark intent
		if GS.Combat() then
			local handOfGuldanCDR = 15-(GetTime()-select(3, GetSpellCharges(105174)))
			local moltenCoreStacks = select(4, GS.Aura("player", 140074)) or 0

			GS.MultiDoT("Corruption")
			GS.MultiDoT("Doom")

			if GS.ValidTarget() then
				if GSR.Thok and UnitChannelInfo("player") and ThokThrottle and ThokThrottle > GetTime() and ThokThrottle-GetTime() <= (1.5/(1+GetHaste()*.01)) then SpellStopCasting() end
				
				if GS.CDs then
					-- actions=potion,name=draenic_intellect,if=buff.bloodlust.react|(buff.dark_soul.up&(trinket.proc.any.react|trinket.stacking_proc.any.react>6)&!buff.demonbolt.remains)|target.health.pct<20
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") end
					if GSR.Race == "Orc" and GS.SIR(33702) then GS.Cast("target", 33702, false, false, false, "SpellToInterrupt") end
					if GSR.Race == "BloodElf" and GS.SIR(28730) then GS.Cast("target", 28730, false, false, false, "SpellToInterrupt") end
					-- actions+=/mannoroths_fury
					if GS.SIR(113861) and GS.PlayerHasTalent(7, 1) and not GS.Aura("player", 113861) and ((GetSpellCharges(113861) == 2 and ((not GS.PlayerHasGlyph(56242) and (GS.Aura("target", 146739, "", "PLAYER") or GS.Trinket("int", "remaining", 10, false, "haste"))) or GS.SpellCDDuration(104316, nil) > 0)) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.Aura("player", 157695) and GS.TTD[ObjectPointer("target")] < select(7, GS.Aura("player", 157695))-GetTime()) or (not GS.Aura("player", 157695) and GS.PP() >= 790)) then GS.Cast("target", 113861, false, false, false, "SpellToInterrupt") return end -- dark soul with demonbolt
					if GS.SIR(113861) and not GS.PlayerHasTalent(7, 1) and (GetSpellCharges(113861) == 2 or not GS.PlayerHasTalent(6, 1) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and (GS.TTD[ObjectPointer("target")] <=20 and not GS.PlayerHasGlyph(159665) or GS.TTD[ObjectPointer("target")] <= 10)) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] <= 60 and GS.PP() > 400) or ((not GS.AuraRemaining("player", 177081, 7.5) or GS.Trinket("int", "remaining", 7.5, true)) and GS.PP() >= 400)) then GS.Cast("target", 113861, false, false, false, "SpellToInterrupt") return end
				end
				
				if GS.CDs and GS.PlayerHasGlyph(56242) and GS.SIR(104316) and not GS.PlayerHasTalent(7, 1) and (GetTime()-GS.CombatStart) > 3 and (GS.Aura("player", 113861) or (GS.SpellCDDuration(113861, nil) > (120/(1/(1/(1+GetHaste()*.01))))) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 32)) then GS.Cast("target", 104316, false, false, false, "SpellToInterrupt") return end -- imp swarm
				
				if GS.PlayerHasTalent(5, 1) then
					if GS.SIR(115831) and GS.PetDistance("target", 8) then GS.Cast("target", 115831, false, false, false, "SpellToInterrupt") return end
					if GS.SIR(115625) and not GS.Aura("pet", 115831) and GS.SpellCDDuration(115831, nil) > 5 then GS.Cast("target", 115625, false, false, false, "SpellToInterrupt") return end
				else
					if GS.SIR(89751) and GS.PetDistance("target", 8) then GS.Cast("target", 89751, false, false, false, "SpellToInterrupt") return end
				end

				if GS.SCA(105174, "target", interruptCasting) and not GS.Aura("player", 103958) and GS.Warlock.HandOfGuldanThrottle == 0 and GS.AuraRemaining("target", 47960, 1.35+(select(4, GetSpellInfo(686))*0.001)) and (not GS.AuraRemaining("target", 47960, 1.35) or ((GS.TierBonus("t17") < 4 and ((GetSpellCharges(105174) == 1 and handOfGuldanCDR < 4) or GetSpellCharges(105174) == 2)) or (GetSpellCharges(105174) == 3 or (GetSpellCharges(105174) == 2 and handOfGuldanCDR < 11.1)) and (GS.SpellCDDuration(152108, nil) > 6 or not GS.PlayerHasTalent(7, 2)))) then GS.Cast("target", 105174, false, false, false, "SpellToInterrupt") return end -- hand of guldan
				if GS.SCA(105174, "target", interruptCasting) and not GS.Aura("player", 103958) and GS.Warlock.HandOfGuldanThrottle == 0 and GS.AuraRemaining("target", 47960, 1.35+(select(4, GetSpellInfo(686))*0.001)) and GS.PlayerHasTalent(7, 1) and (not GS.AuraRemaining("target", 47960, 1.35) or ((GS.TierBonus("t17") < 4 and (GetSpellCharges(105174) == 2 or (GetSpellCharges(105174) == 1 and handOfGuldanCDR < 4))) or (GetSpellCharges(105174) == 3 or (GetSpellCharges(105174) == 2 and handOfGuldanCDR < 11.1)))) then GS.Cast("target", 105174, false, false, false, "SpellToInterrupt") return end -- hand of guldan
				if GS.SCA(105174, "target", interruptCasting) and not GS.Aura("player", 103958) and GS.Warlock.HandOfGuldanThrottle == 0 and GS.AuraRemaining("target", 47960, 3.7) and (GetTime()-GS.CombatStart) < 5 and (not GS.Aura("player", 157695) or select(7, GS.Aura("player", 157695))-GetTime() < 1.5/(1+GetHaste()*.001)*2) and (GetSpellCharges(105174) >= 2 or GS.TierBonus("t17") < 4) and GetSpellCharges(113861) >= 1 then GS.Cast("target", 105174, false, false, false, "SpellToInterrupt") return end -- hand of guldan
				
				if GS.CDs then
					if GS.PlayerHasTalent(5, 2) then
						-- actions+=/service_pet,if=talent.grimoire_of_service.enabled&(target.time_to_die>120|target.time_to_die<20|(buff.dark_soul.remains&target.health.pct<20))
					end
					if not GS.PlayerHasTalent(7, 3) then
						if GS.SIR(112927) and GS.TargetCount(10) < 5 then GS.Cast("target", 112927, false, false, false, "SpellToInterrupt") return end
						if GS.SIR(1122) and GS.TargetCount(10) >= 5 then GS.Cast("target", 1122, false, false, false, "SpellToInterrupt") return end
					end
				end

				if GS.PlayerHasTalent(7, 1) then

					if GS.Aura("player", 103958) then
						if GS.SIR(104025) and not GS.Aura("player", 104025) and not GS.IsCAOCH() and GS.PP() > 450 and GS.PlayerCount(10) >= 5 then GS.Cast("target", 104025, false, false, false, "SpellToInterrupt") return end -- immolation aura
						if GS.SIR(603) and #GS.PullEnemies(40, true) >= 6 and (not GS.Aura("player", 113861) or not GS.PlayerHasGlyph(159665)) then
							if GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 30*(1/(1+GetHaste()*.01)) and GS.AuraRemaining("target", 603, 18, "Metamorphosis", "PLAYER") then GS.Cast("target", 603, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #tNoObjectDoom do
									if GS.TTD[ObjectPointer(tNoObjectDoom[i])] and GS.TTD[ObjectPointer(tNoObjectDoom[i])] >= 30*(1/(1+GetHaste()*.01)) then GS.Cast(tNoObjectDoom[i], 603, false, false, false, "SpellToInterrupt") return end
								end
								for i = 1, #tDoom do
									if GS.TTD[ObjectPointer(tDoom[i])] and GS.TTD[ObjectPointer(tDoom[i])] >= 30*(1/(1+GetHaste()*.01)) and GS.AuraRemaining(tDoom[i], 603, 18, "Metamorphosis", "PLAYER") then GS.Cast(tDoom[i], 603, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						-- actions.db+=/kiljaedens_cunning,moving=1,if=buff.demonbolt.stack=0|(buff.demonbolt.stack<4&buff.demonbolt.remains>=(40*spell_haste-execute_time))
						if GS.SCA(157695, "target", interruptCasting) and (not GS.Aura("player", 157695) or (not GS.AuraStacks("player", 157695, 4) and not GS.AuraRemaining("player", 157695, 40*(1/(1+GetHaste()*.01))-select(4, GetSpellInfo(157695))*0.001))) then GS.Cast("target", 157695, false, false, false, "SpellToInterrupt") return end -- demonbolt
						if GS.SIR(603) and (not GS.Aura("player", 113861) or not GS.PlayerHasGlyph(159665)) then
							if GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 30*(1/(1+GetHaste()*.01)) and GS.AuraRemaining("target", 603, 18, "Metamorphosis", "PLAYER") then GS.Cast("target", 603, false, false, false, "SpellToInterrupt") return
							elseif GS.AoE then
								for i = 1, #tNoObjectDoom do
									if GS.TTD[ObjectPointer(tNoObjectDoom[i])] and GS.TTD[ObjectPointer(tNoObjectDoom[i])] >= 30*(1/(1+GetHaste()*.01)) then GS.Cast(tNoObjectDoom[i], 603, false, false, false, "SpellToInterrupt") return end
								end
								for i = 1, #tDoom do
									if GS.TTD[ObjectPointer(tDoom[i])] and GS.TTD[ObjectPointer(tDoom[i])] >= 30*(1/(1+GetHaste()*.01)) and GS.AuraRemaining(tDoom[i], 603, 18, "Metamorphosis", "PLAYER") then GS.Cast(tDoom[i], 603, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
					else
						if GS.SIR(172) then -- corruption cycle
							if GS.SCA(172, "target", true) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 6 and GS.AuraRemaining("target", 146739, 5.4, "", "PLAYER") then GS.Cast("target", 172, false, false, false, "Hellfire")
							elseif GS.AoE then
								for i = 1, #tNoObjectCorruption do
									if GS.SCA(172, tNoObjectCorruption[i], true) and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] >= 6 then GS.Cast(tNoObjectCorruption[i], 172, false, false, false, "Hellfire") return end
								end
								for i = 1, #tCorruption do
									if GS.SCA(172, tCorruption[i], true) and GS.TTD[ObjectPointer(tCorruption[i])] and GS.TTD[ObjectPointer(tCorruption[i])] >= 6 and GS.AuraRemaining(tCorruption[i], 146739, 5.4, "", "PLAYER") then GS.Cast(tCorruption[i], 172, false, false, false, "Hellfire") return end
								end
							end
						end
					end

					if GS.Aura("player", 103958) then
						if GS.AuraStacks("player", 157695, 4) and GS.PP() <= 600 and GS.TTD[ObjectPointer("target")] and not GS.AuraRemaining("player", 157695, GS.TTD[ObjectPointer("target")]) and not GS.Aura("player", 113861) and not GS.IsCAOCH() then CancelUnitBuff("player", "Metamorphosis") return end

						if GS.SCA(124916, "target", interruptCasting) and GS.Aura("player", 113861) and GS.TargetCount(6) >= 2 and GS.PP() > 450 then GS.Cast("target", 124916, false, false, false, "SpellToInterrupt") return end -- chaos wave
						if GS.SCA(6353, "target", interruptCasting) and GS.Aura("player", 140074) then -- soul fire
							if (not GS.AuraRemaining("player", 113861, select(4, GetSpellInfo(6353))*0.001) and GS.PP() >= 175) or (GS.TTD[ObjectPointer("target")] and GS.Aura("player", 157695) and GS.TTD[ObjectPointer("target")] < select(7, GS.Aura("player", 157695))-GetTime()) then GS.Cast("target", 6353, false, false, false, "SpellToInterrupt") return end
							if GS.Health("target", maxhealth, true) <= 25 and GS.PP() >= 750 and GS.Aura("player", 157695) and (GS.PP()-80)/800 > (select(7, GS.Aura("player", 157695))-GetTime())/(40*(1/(1+GetHaste()*.01))) then GS.Cast("target", 6353, false, false, false, "SpellToInterrupt") return end -- soul fire
						end
						if GS.SIR(103964) and GS.PP() > 750 then
							if GS.SCA(103964, "target", interruptCasting) and GS.Aura("target", 146739) and GS.AuraRemaining("target", 146739, 17.4) then 
								GS.Cast("target", 103964, false, false, false, "SpellToInterrupt")
								return
							elseif GS.AoE then
								for i = 1, #tCorruption do
									if GS.SCA(103964, tCorruption[i], interruptCasting) and GS.Aura(tCorruption[i], 146739) and GS.AuraRemaining(tCorruption[i], 146739, 17.4) then GS.Cast(tCorruption[i], 103964, false, false, false, "SpellToInterrupt") return end
								end
							end
						end
						if GS.SCA(103964, "target", interruptCasting) and ((GS.Aura("player", 157695) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < select(7, GS.Aura("player", 157695))-GetTime()) or (GS.PP() >= 750 and GS.Aura("player", 157695))) then GS.Cast("target", 103964, false, false, false, "SpellToInterrupt") return end -- touch of chaos
						if GS.SCA(103964, "target", interruptCasting) and GS.PP() >= 750 and (GS.PP()-40)/800 > (select(7, GS.Aura("player", 157695))-GetTime())/(40*(1/(1+GetHaste()*.01))) then GS.Cast("target", 103964, false, false, false, "SpellToInterrupt") return end -- touch of chaos
					elseif GS.SIR(103958) then -- meta
						if not GS.AuraRemaining("player", 113861, 1.5/(1+GetHaste()*.001)) and (GS.PP() >= 470 or GS.AuraRemaining("player", 113861, (select(4, GetSpellInfo(157695))*0.001)*3)) and (not GS.Aura("player", 157695) or (GS.Aura("player", 157695) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < select(7, GS.Aura("player", 157695))-GetTime())) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end
						if not GS.Aura("player", 157695) and GS.PP() >= 480 and (GetSpellCharges(113861) == 0 or (not GS.PlayerHasTalent(6, 1) and GS.SpellCDDuration(113861, nil) > 0)) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end
						if GS.TTD[ObjectPointer("target")] and GS.Aura("player", 157695) and (GS.PP()/80)*2*(1/(1+GetHaste()*.01)) >= GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < select(7, GS.Aura("player", 157695))-GetTime() then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end
						if (GetTime()-GS.CombatStart) > 10 and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 30*(1/(1+GetHaste()*.01)) and not GS.Aura("target", 603) and not GS.Aura("player", 113861) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end
						if GS.PP() > 750 and (not GS.AuraRemaining("player", 157695, GS.SpellCDDuration(103958)) or (not GS.Aura("player", 157695) and GS.SpellCDDuration(103958, nil) == 0) or select(7, GS.Aura("player", 157695))-GetTime() == GS.SpellCDDuration(103958, nil)) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end 
						if GS.Aura("player", 157695) then
							local remaining = select(7, GS.Aura("player", 157695))-GetTime()
							if not GS.AuraRemaining("player", 157695, 10) and GS.AuraRemaining("target", 603, 18, "Metamorphosis", "PLAYER") and ((GS.PP()-120)/800) > remaining/(40*(1/(1+GetHaste()*.01))) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end
						end 
					end

					if GS.Aura("player", 103958) and GS.SpellCDDuration(61304, nil) == 0 and not GS.IsCAOCH() then
						CancelUnitBuff("player", "Metamorphosis")
						return
					elseif not GS.Aura("player", 103958) then
						if GS.PlayerHasGlyph(56242) and GS.SIR(104316) then GS.Cast("target", 104316, false, false, false, "SpellToInterrupt") return end -- imp swarm
						if GS.AoE and GS.SIR(1949) and not GS.IsCAOCH() and GS.PlayerCount(10) >= 5 and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
						if GS.SCA(6353, "target", true) and GS.Aura("player", 140074) and ((GS.Aura("player", 113861) and GS.AuraRemaining("player", 113861, select(4, GetSpellInfo(686))*0.001)) or (GS.Aura("player", 113861) and not GS.AuraRemaining("player", 113861, select(4, GetSpellInfo(6353))*0.001))) then GS.Cast("target", 6353, false, false, false, "Hellfire") return end -- soul fire
						if GS.SIR(1454) and not GS.IsCAOCH() and GS.PM() < 40 and not GS.Aura("player", 113861) then GS.Cast("target", 1454, false, false, false, "Hellfire") return end -- life tap player mana less than 40
						if GS.AoE and GS.SIR(1949) and not GS.IsCAOCH() and GS.PlayerCount(10) >= 4 and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
						if GS.SCA(686, "target", true) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 137587)) then GS.Cast("target", 686, false, false, false, "Hellfire") return end -- shadow bolt
						if GS.SIR(1949) and not GS.IsCAOCH() and IsPlayerMoving() and GS.PlayerCount() and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
						if GS.SIR(1454) and not GS.IsCAOCH() then GS.Cast("player", 1454, false, false, false, "SpellToInterrupt") return end -- life tap if nothing else
					end
					return
				end

				-- actions+=/kiljaedens_cunning,if=!cooldown.cataclysm.remains&buff.metamorphosis.up
				
				if GS.Aura("player", 103958) then
					if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) then
						local x, y, z = GS.SmartAoE(40, 8, true)
						GS.Cast(nil, 152108, x, y, z, "SpellToInterrupt")
						return
					end -- cataclysm
					if GS.SIR(104025) and not GS.Aura("player", 104025) and not GS.IsCAOCH() and GS.PP() > 450 and GS.PlayerCount(10) >= 3 then GS.Cast("target", 104025, false, false, false, "SpellToInterrupt") return end -- immolation aura
					if GS.SIR(603) and (not GS.Aura("player", 113861) or not GS.PlayerHasGlyph(159665)) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 30*(1/(1+GetHaste()*.01)) and GS.AuraRemaining("target", 603, 18, "Metamorphosis", "PLAYER") then GS.Cast("target", 603, false, false, false, "SpellToInterrupt") return end -- doom
				else
					if GS.SIR(172) then -- corruption cycle
						if GS.SCA(172, "target", true) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 6 and GS.AuraRemaining("target", 146739, 5.4, "", "PLAYER") then GS.Cast("target", 172, false, false, false, "Hellfire")
						elseif GS.AoE then
							for i = 1, #tNoObjectCorruption do
								if GS.SCA(172, tNoObjectCorruption[i], true) and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] and GS.TTD[ObjectPointer(tNoObjectCorruption[i])] >= 6 then GS.Cast(tNoObjectCorruption[i], 172, false, false, false, "Hellfire") return end
							end
							for i = 1, #tCorruption do
								if GS.SCA(172, tCorruption[i], true) and GS.TTD[ObjectPointer(tCorruption[i])] and GS.TTD[ObjectPointer(tCorruption[i])] >= 6 and GS.AuraRemaining(tCorruption[i], 146739, 5.4, "", "PLAYER") then GS.Cast(tCorruption[i], 172, false, false, false, "Hellfire") return end
							end
						end
					end
				end

				if GS.Aura("player", 103958) then
					if ((GS.PP() <650 and not GS.PlayerHasGlyph(159665)) or GS.PP() < 450) and not GS.Aura("player", 113861) and (not GS.Aura("player", 177081) and not GS.Trinket("int", "active") or GS.PP() < (800 - GS.SpellCDDuration(113861, nil) * (10/(1/(1+GetHaste()*.01))))) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 20 then CancelUnitBuff("player", "Metamorphosis") return end
					if GetSpellCharges(105174) > 0 and GS.Aura("target", 47960, "", "PLAYER") and GS.AuraRemaining("target", 47960, 1.35+(select(4, GetSpellInfo(686))*0.001), "", "PLAYER") and GS.PP() < 100 and not GS.AuraRemaining("player", 113861, 10) then CancelUnitBuff("player", "Metamorphosis") return end
					if GetSpellCharges(105174) == 3 and (GS.AuraRemaining("player", 113861, (1.5/(1+GetHaste()*.01))) or GS.SpellCDDuration(103958, nil) < (1.5/(1+GetHaste()*.01))) then CancelUnitBuff("player", "Metamorphosis") return end

					if GS.SCA(124916, "target", interruptCasting) and ((GS.Aura("player", 113861) and GS.TargetCount(6) >= 2) or (GetSpellCharges(124916) == 3 or GetSpellCharges(124916) == 2 and GS.TierBonus("t17") < 4)) then GS.Cast("target", 124916, false, false, false, "SpellToInterrupt") return end
					if GS.SCA(6353, "target", interruptCasting) and GS.Aura("player", 140074) and (GS.Health("target", maxhealth, true) <= 25 or not GS.AuraRemaining("player", 113861, select(4, GetSpellInfo(6353))*0.001)) and (not IsEquippedItem(113984) or not GS.Aura("player", 177081) or ((moltenCoreStacks*(select(4, GetSpellInfo(6353))*0.001) >= (select(7, GS.Aura("player", 177081))-GetTime())-1 or GS.PP() <= math.ceil(((select(7, GS.Aura("player", 177081))-GetTime())-moltenCoreStacks*select(4, GetSpellInfo(6353))*0.001)*40)+80*moltenCoreStacks) or GS.Health("target", maxhealth, true) <= 25) and not GS.AuraRemaining("player", 177081, select(4, GetSpellInfo(6353))*0.001)) then GS.Cast("target", 6353, false, false, false, "SpellToInterrupt") return end
					if GS.SIR(103964) and GS.PP() > 750 then -- touch of chaos corruption extend
						if GS.SCA(103964, "target", interruptCasting) and GS.Aura("target", 146739) and GS.AuraRemaining("target", 146739, 17.4) then 
							GS.Cast("target", 103964, false, false, false, "SpellToInterrupt")
							return
						elseif GS.AoE then
							for i = 1, #tCorruption do
								if GS.SCA(103964, tCorruption[i], interruptCasting) and GS.Aura(tCorruption[i], 146739) and GS.AuraRemaining(tCorruption[i], 146739, 17.4) then GS.Cast(tCorruption[i], 103964, false, false, false, "SpellToInterrupt") return end
							end
						end
					end
					if GS.SCA(103964, "target", interruptCasting) then GS.Cast("target", 103964, false, false, false, "SpellToInterrupt") return end -- touch of chaos
				else
					if GS.SIR(103958) and not GS.IsCAOCH() then -- meta
						if not GS.AuraRemaining("player", 113861, (1.5/(1+GetHaste()*.01))) and (GS.PP() > 300 or not GS.PlayerHasGlyph(159665)) and (GS.PP() >= 80 and moltenCoreStacks >= 1 or GS.PP() >= 40) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end -- 
						if (GS.Aura("player", 177081) or GS.Trinket("int", "active")) and ((GS.PP() > 450 and 60-(GetTime()-select(3, GetSpellCharges(113861))) >= 10 and GS.PlayerHasGlyph(159665)) or (GS.PP() > 650 and GS.SpellCDDuration(113861, nil) >= 10)) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end --
						if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end -- cata
						if GS.PP() > 300 and not GS.Aura("target", 603, "", "Metamorphosis") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] >= 30/(1/(1/(1+GetHaste()*.01))) then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end -- doom
						if (GS.PP() > 750 and (GetSpellCharges(105174) == 0 or (not GS.Aura("target", 47960, "", "PLAYER") and GS.Warlock.HandOfGuldanThrottle == 0--[[action.hand_of_guldan.in_flight_to_target]]))) or GS.TTD[ObjectPointer("target")] and math.floor(GS.PP()/80)*(select(4, GetSpellInfo(6353))*0.001) >= GS.TTD[ObjectPointer("target")] then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end -- hand of guldan or soulfire
						if GS.PP() >= 950 then GS.Cast("target", 103958, false, false, false, "SpellToInterrupt") return end -- demonic fury cap
					end
				end

				if GS.Aura("player", 103958) and GS.SpellCDDuration(61304, nil) == 0 and not GS.IsCAOCH() then
					CancelUnitBuff("player", "Metamorphosis")
					return
				else
					if GS.PlayerHasGlyph(56242) and GS.SIR(104316) then GS.Cast("target", 104316, false, false, false, "SpellToInterrupt") return end -- imp swarm
					if GS.AoE and GS.SIR(1949) and not GS.IsCAOCH() and GS.PlayerCount(10) >= 5 and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
					if GS.SCA(6353, "target", interruptCasting) and GS.Aura("player", 140074) and (moltenCoreStacks >=7 or GS.Health("target", maxhealth, true) <= 25 or (GS.Aura("player", 113861) and GS.SpellCDDuration(103958, nil) > select(7, GS.Aura("player", 113861))-GetTime()) or GS.Trinket("int", "remaining", select(4, GetSpellInfo(6353))*0.001, true) or not GS.AuraRemaining("player", 177081, (select(4, GetSpellInfo(6353))*0.001))) and (GS.AuraRemaining("player", 113861, (select(4, GetSpellInfo(686))*0.001)) or not GS.AuraRemaining("player", 113861, (select(4, GetSpellInfo(6353))*0.001))) then GS.Cast("target", 6353, false, false, false, "SpellToInterrupt") return end -- soul fire # 1
					if GS.SCA(6353, "target", interruptCasting) and GS.Aura("player", 140074) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < ((GetTime()-GS.CombatStart)+GS.TTD[ObjectPointer("target")])*.25+GS.SpellCDDuration(113861, nil) then GS.Cast("target", 6353, false, false, false, "SpellToInterrupt") return end -- soul fire if time running out
					if GS.SIR(1454) and not GS.IsCAOCH() and GS.PM() < 40 and not GS.Aura("player", 113861) then GS.Cast("target", 1454, false, false, false, "Hellfire") return end -- life tap player mana less than 40
					if GS.AoE and GS.SIR(1949) and not GS.IsCAOCH() and GS.PlayerCount(10) >= 4 and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
					if GS.SCA(686, "target", true) and (not IsPlayerMoving() or GS.Aura("player", 172106) or GS.Aura("player", 137587)) then GS.Cast("target", 686, false, false, false, "Hellfire") return end -- shadow bolt
					if GS.SIR(1949) and not GS.IsCAOCH() and IsPlayerMoving() and (not GSR.Thok or ThokThrottle < GetTime() or ThokThrottle-GetTime() > (1.5/(1+GetHaste()*.01))) then GS.Cast("target", 1949, false, false, false, "SpellToInterrupt") return end -- hellfire
					if GS.SIR(1454) and not GS.IsCAOCH() then GS.Cast("player", 1454, false, false, false, "SpellToInterrupt") return end -- life tap if nothing else
				end
			end
		end
		if GS.Aura("player", 103958) and not GS.Combat() then CancelUnitBuff("player", "Metamorphosis") return end
	end

	function GS.WARLOCK3() -- destruction  -- todo: aoe, cooldowns, chaosbolt vomit @warlock
		if not IsMounted() and (not GetRaidBuffTrayAuraInfo(5) or not GetRaidBuffTrayAuraInfo(8)) then GS.Cast("player", 109773, false, false, false, "SpellToInterrupt") return end -- dark intent
		-- actions.precombat+=/summon_pet,if=!talent.demonic_servitude.enabled&(!talent.grimoire_of_sacrifice.enabled|buff.grimoire_of_sacrifice.down)
		if GS.Combat() then
			for i = 1, #GS.Targets do if not GS.Warlock.ImmolateThrottle[UnitGUID(GS.Targets[i])] then GS.Warlock.ImmolateThrottle[UnitGUID(GS.Targets[i])] = 0 end end
			GS.MultiDoT("Immolate")
			if GS.ValidTarget() then

				-- actions=potion,name=draenic_intellect,if=buff.bloodlust.react|target.health.pct<=20
				-- actions+=/berserking
				-- actions+=/blood_fury
				-- actions+=/arcane_torrent
				-- actions+=/mannoroths_fury
				-- actions+=/dark_soul,if=!talent.archimondes_darkness.enabled|(talent.archimondes_darkness.enabled&(charges=2|trinket.proc.any.react|trinket.stacking_any.intellect.react>6|target.time_to_die<40))
				-- actions+=/service_pet,if=talent.grimoire_of_service.enabled&(target.time_to_die>120|target.time_to_die<20|(buff.dark_soul.remains&target.health.pct<20))
				-- actions+=/summon_doomguard,if=!talent.demonic_servitude.enabled&active_enemies<5
				-- actions+=/summon_infernal,if=!talent.demonic_servitude.enabled&active_enemies>=5
				
				if GS.TargetCount(10) >= 6 then
					if GS.SIR(104232) and not GS.IsCAOCH() and GS.AuraRemaining("player", 104232, 1) then
						local x,y,z = GS.SmartAoE(40, 8, true, tableReturn)
						GS.Cast("target", 104232, x, y, z, "SpellToInterrupt")
						return
					end
					
					-- actions.aoe+=/havoc,target=2
					-- actions.aoe+=/shadowburn,if=buff.havoc.remains
					-- actions.aoe+=/chaos_bolt,if=buff.havoc.remains>cast_time&buff.havoc.stack>=3
					
					-- actions.aoe+=/kiljaedens_cunning,if=(talent.cataclysm.enabled&!cooldown.cataclysm.remains)
					-- actions.aoe+=/kiljaedens_cunning,moving=1,if=!talent.cataclysm.enabled

					if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) then
						local x,y,z = GS.SmartAoE(40, 8, true, tableReturn)
						GS.Cast("target", 152108, x, y, z, "SpellToInterrupt")
						return
					end
					if GS.SIR(108683) and GS.PP() >= 10 and not GS.Aura("player", 108683) then GS.Cast("target", 108683, false, false, false, "SpellToInterrupt") end -- fire and brimstone
					if GS.Aura("player", 108683) then
						-- actions.aoe+=/immolate,if=!dot.immolate.ticking
						if GS.SCA(17962, "target", interruptCasting) and GetSpellCharges(17962) == 2 then GS.Cast("target", 17962, false, false, false, "SpellToInterrupt") return end -- conflagrate
						-- actions.aoe+=/immolate,if=dot.immolate.remains<=(dot.immolate.duration*0.3)
						if GS.PlayerHasTalent(7, 1) and GS.Aura("player", 108683) and GS.PP() >= 25 and GS.SCA(116858, "target", interruptCasting) then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end -- chaos bolt
					end
					if GS.SCA(29722, "target", interruptCasting) then GS.Cast("target", 29722, false, false, false, "SpellToInterrupt") return end -- incinerate
					return
				end

				-- actions.single_target=havoc,target=2
				if GS.SCA(17877, "target", interruptCasting) and GS.PlayerHasTalent(7, 1) and (GS.PP() >= 25 or GS.Aura("player", 113861) or GS.TTD[ObjectPointer("target")] < 10) then GS.Cast("target", 17877, false, false, false, "SpellToInterrupt") return end -- shadowburn
				-- actions.single_target+=/kiljaedens_cunning,if=(talent.cataclysm.enabled&!cooldown.cataclysm.remains)
				-- actions.single_target+=/kiljaedens_cunning,moving=1,if=!talent.cataclysm.enabled
				if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) and GS.TargetCount(8) > 1 then
					local x,y,z = GS.SmartAoE(40, 8, true, tableReturn)
					GS.Cast("target", 152108, x, y, z, "SpellToInterrupt")
					return
				end

				if GS.SCA(348) and (not GS.PlayerHasTalent(7, 2) or GS.SpellCDDuration(152108, nil) > (select(4, GetSpellInfo(348))*0.001)) and GS.Warlock.ImmolateThrottle[UnitGUID("target")] == 0 and GS.AuraRemaining("target", 157736, select(4, GetSpellInfo(348))*0.001, "", "PLAYER") then -- immolate cast time
					if GS.TargetCount(10) > 4 and GS.PP() > 9 and not GS.Aura("player", 108683) then GS.Cast("target", 108683, false, false, false, "SpellToInterrupt") end -- fire and brimstone for 5 targets
					GS.Cast("target", 348, nil)
					return 
				elseif GS.AoE and GS.SIR(348) then
					for i = 1, #tImmolate do
						if GS.SCA(348, tImmolate[i]) and GS.Warlock.ImmolateThrottle[UnitGUID(tImmolate[i])] == 0 and GS.AuraRemaining(tImmolate[i], 157736, select(4, GetSpellInfo(348))*0.001, "", "PLAYER") then GS.Cast(tImmolate[i], 348, nil) return end
					end
					for i = 1, #tNoObjectImmolate do
						if GS.SCA(348, tNoObjectImmolate[i]) and GS.Warlock.ImmolateThrottle[UnitGUID(tNoObjectImmolate[i])] == 0 then GS.Cast(tNoObjectImmolate[i], 348, nil) return end
					end
				end
				if GS.Aura("player", 108683) and not GS.AuraRemaining("target", 157736, 4.5) then CancelUnitBuff("player", "Fire and Brimstone") end

				-- actions.single_target+=/shadowburn,if=buff.havoc.remains
				-- actions.single_target+=/chaos_bolt,if=buff.havoc.remains>cast_time&buff.havoc.stack>=3

				if GS.SCA(17962) and GetSpellCharges(17962) == 2 then GS.Cast("target", 17962, nil) return end -- conflagrate

				if GS.PlayerHasTalent(7, 2) and GS.SIR(152108) then
					local x,y,z = GS.SmartAoE(40, 8, true, tableReturn)
					GS.Cast("target", 152108, x, y, z, "SpellToInterrupt")
					return
				end
				if GS.SIR(104232) and (GS.TargetCount(8) > 4 or GS.Aura("player", 108508) and GS.TargetCount(18) > 2) and GS.AuraRemaining("player", 104232, 1) then GS.Cast("target", 104232, false, false, false, "SpellToInterrupt") return end -- rain of fire

				if GS.PlayerHasTalent(7, 1) then -- chaos bolt charred remains
					if GS.SCA(116858, "target", interruptCasting) and GS.TargetCount(10) > 1 and GS.Health("target", maxhealth, true) > 20 then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end
					if GS.SCA(116858, "target", interruptCasting) and not GS.AuraStacks("player", 117828, 3) and GS.PP() >= 25 then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end
				end
				if GS.SCA(116858, "target", interruptCasting) and not GS.AuraStacks("player", 117828, 3) then -- chaos bolt
					if GS.PP() >= 35 or GS.Aura("player", 113861) or GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 20 then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end -- general
					if GS.TierBonus("t17") >= 2 and GS.PP() >= 25 then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end -- prevent cap from tier 17 two piece
					if not GS.AuraRemaining("player", 177159, (select(4, GetSpellInfo(116858))*0.001)) or not GS.AuraRemaining("player", 177176, (select(4, GetSpellInfo(116858))*0.001)) then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end -- legendary ring proc
					if GS.Trinket("int", "remaining", (select(4, GetSpellInfo(116858))*0.001), true) then GS.Cast("target", 116858, false, false, false, "SpellToInterrupt") return end -- trinket procs (includes haste which is a no no for now)

					-- actions.single_target+=/chaos_bolt,if=trinket.proc.intellect.react&trinket.proc.intellect.remains>cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.stacking_proc.intellect.react>7&trinket.stacking_proc.intellect.remains>=cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.proc.crit.react&trinket.proc.crit.remains>cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.stacking_proc.multistrike.react>=8&trinket.stacking_proc.multistrike.remains>=cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.proc.multistrike.react&trinket.proc.multistrike.remains>cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.proc.versatility.react&trinket.proc.versatility.remains>cast_time
					-- actions.single_target+=/chaos_bolt,if=trinket.proc.mastery.react&trinket.proc.mastery.remains>cast_time
				end

				if GS.SCA(348) and GS.Warlock.ImmolateThrottle[UnitGUID("target")] == 0 and GS.AuraRemaining("target", 157736, 4.5, "", "PLAYER") then
					if GS.TargetCount(10) > 4 and GS.PP() > 9 and not GS.Aura("player", 108683) then GS.Cast("target", 108683, false, false, false, "SpellToInterrupt") end -- fire and brimstone for 5 targets
					GS.Cast("target", 348, nil)
					return
				elseif GS.AoE and GS.SIR(348) then
					for i = 1, #tNoObjectImmolate do
						if GS.SCA(348, tNoObjectImmolate[i]) and GS.Warlock.ImmolateThrottle[UnitGUID(tNoObjectImmolate[i])] == 0 and GS.AuraRemaining(tNoObjectImmolate[i], 157736, 4.5, "", "PLAYER") then GS.Cast(tNoObjectImmolate[i], 348, nil) return end
					end
					for i = 1, #tImmolate do
						if GS.SCA(348, tImmolate[i]) and GS.Warlock.ImmolateThrottle[UnitGUID(tImmolate[i])] == 0 and GS.AuraRemaining(tImmolate[i], 157736, 4.5, "", "PLAYER") then GS.Cast(tImmolate[i], 348, nil) return end
					end
				end
				if GS.SCA(17962) then GS.Cast("target", 17962, nil) return end -- conflagrate
				if GS.SCA(29722) then GS.Cast("target", 29722, nil) return end -- incinerate
			end
			return
		end
		table.wipe(GS.Warlock.ImmolateThrottle)
	end

	function GS.MONK1() -- brewmaster
		if not IsMounted() and GS.SIR(116781) and (not GetRaidBuffTrayAuraInfo(1) or not GetRaidBuffTrayAuraInfo(6)) then GS.Cast("player", 116781, nil) return end
		if GS.Combat() then
			local guardRechargeTime = 30-(GetTime()-select(3, GetSpellCharges(115295)))
			local chibrewcd = 60-(GetTime()-select(3, GetSpellCharges(115399)))
			local _, energyregen = GetPowerRegen()
			local energytimetomax = (100-UnitPower("player"))/energyregen

			if GS.ValidTarget() then
				StartAttack("target")
				if GS.CDs and GS.SIR(33697) and GSR.Race == "Orc" and UnitPower("player") <= 40 then GS.Cast("player", 33697, nil) return end -- bloodfury
				if GS.CDs and GS.SIR(26297) and GSR.Race == "Troll" and UnitPower("player") <= 40 then GS.Cast("player", 26297, nil) return end -- bloodfury
				if GS.CDs and GS.SIR(129597) and GSR.Race == "BloodElf" and UnitPower("player") <= 40 then GS.Cast("player", 129597, nil) return end -- bloodfury
				if GS.PlayerHasTalent(3, 3) and GS.SIR(115399) then
					if GS.PP(true) - GS.PP() >= 2 and not GS.AuraStacks("player", 128939, 11) and ((GetSpellCharges(115399) == 1 and chibrewcd < 5) or GetSpellCharges(115399) == 2 or GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 15) then GS.Cast("player", 115399, nil) return end -- chi brew dump
					if GS.PP() == 0 and GS.Aura("player", 124273) or GS.PP() < 2 and not GS.Aura("player", 115307) then GS.Cast("player", 115399, false, false, false, "SpellToInterrupt") return end -- chi brew to set up defenses
				end

				if GS.CDs and GS.PlayerHasTalent(6, 2) and GS.SIR(123904) and not GS.Aura("player", 152173) and not GS.AuraRemaining("player", 115307, 3) and GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and GS.TTD[ObjectPointer("target")] > 15 then GS.Cast("target", 123904, nil) return end -- xuen
				if GS.CDs and GS.PlayerHasTalent(7, 3) and GS.SpellCDDuration(121253, nil) > 6 then GS.Cast("player", 152173, nil) return end -- serenity
				-- actions+=/potion,name=draenic_armor,if=(buff.fortifying_brew.down&(buff.dampen_harm.down|buff.diffuse_magic.down)&buff.elusive_brew_activated.down)
					
				if GS.AoE and GS.PlayerCount(8) >= 3 then
					if GS.SIR(119582) and GS.Aura("player", 124273) then GS.Cast("player", 119582, nil) return end -- purifying brew heavy stagger
					if not GS.PlayerHasTalent(7, 2) and GS.SCA(100784) and not GS.Aura("player", 115307) then GS.Cast("target", 100784, nil) return end -- blackout kick shuffle keg smash
					if GS.SIR(119582) and GS.Aura("player", 152173) then GS.Cast("player", 119582, nil) end -- purifying brew heavy stagger
					if GS.SIR(119582) and not GS.PlayerHasTalent(7, 2) and GS.Aura("player", 124274) and not GS.AuraRemaining("player", 115307, 6) then GS.Cast("player", 119582, false, false, false, "SpellToInterrupt") end
					if GS.SIR(115295) and (GetSpellCharges(115295) == 2 or GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 15 or GetSpellCharges(115295) == 1 and guardRechargeTime < 5) then GS.Cast("player", 115295, nil) return end -- guard
					if GS.SIR(115295) and select(2, GS.Resolve()) >= UnitHealthMax("player")*.5 then GS.Cast("target", 115295, false, false, false, "SpellToInterrupt") return end -- guard emergency
					if not GS.PlayerHasTalent(7, 2) and GS.SIR(115181) and (GS.PP() >= 3 or GS.Aura("player", 152173)) and not GS.AuraRemaining("player", 115307, 6) and GS.AuraRemaining("target", 123725, 2.4, "", "PLAYER") then GS.Cast("target", 115181, nil) return end -- breath of fire
					if GS.SCA(121253) and GS.PP(true) - GS.PP() >= 1 and not GS.Aura("player", 152173) then GS.Cast("target", 121253, nil) return end -- keg smash
					if GS.PlayerHasTalent(6, 1) and GS.PP(true) - GS.PP() >= 1 and not GS.Aura("player", 152173) and GS.SIR(116847) then GS.Cast("target", 116847, nil) return end -- rushing jade wind
					if GS.PlayerHasTalent(2, 3) and GS.SIR(123986) and (UnitPower("player")+(energyregen)) < 100 and GS.IsFacing("player", "target") then GS.Cast("target", 123986, false, false, false, "SpellToInterrupt") return end -- chi burst
					if GS.PlayerHasTalent(2, 1) and (UnitPower("player")+(energyregen)) < 100 and GS.SIR(115098) then GS.Cast("target", 115098, nil) return end -- chi wave
					if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and (UnitPower("player")+(energyregen)) < 100 then
						if not GS.Aura("player", 124081) then GS.Cast("player", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere self
						if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
					end
					if GS.PlayerHasTalent(7, 2) and GS.PP() >= 4 and GS.SCA(157676) then GS.Cast("target", 157676, nil) return end -- chi explosion
					if GS.SCA(100784) and GS.PP() >= 4 then GS.Cast("target", 100784, nil) return end -- blackout kick
					if not GS.PlayerHasTalent(7, 2) and GS.SCA(100784) and GS.AuraRemaining("player", 115307, 3) and GS.SpellCDDuration(121253, nil) >= 1 then GS.Cast("target", 100784, nil) return end -- blackout kick shuffle keg smash
					if GS.SCA(100784) and GS.Aura("player", 152173) then GS.Cast("target", 100784, nil) return end -- blackout kick spam serenity
					if GS.SIR(115072) and GS.PP(true) - GS.PP() >= 1 and GS.SpellCDDuration(121253, nil) >= 1 and (UnitPower("player")+(energyregen*GS.SpellCDDuration(121253, nil))) >= 80 then GS.Cast("player", 115072, nil) return end -- expel harm
					if GS.SCA(100780) and GS.PP(true) - GS.PP() >= 1 and GS.SpellCDDuration(121253, nil) >= 1 and GS.SpellCDDuration(115072, nil) >= 1 and (UnitPower("player")+(energyregen*GS.SpellCDDuration(121253, nil))) >= 80 then GS.Cast("target", 100780, nil) return end -- jab
					if GS.SCA(100787) then GS.Cast("target", 100787, nil) return end -- tiger palm
				end

				if GS.SIR(119582) and not GS.PlayerHasTalent(7, 2) and GS.Aura("player", 124273) then GS.Cast("player", 119582, nil) end -- purifying brew heavy stagger
				if GS.SCA(100784) and not GS.Aura("player", 115307) then GS.Cast("target", 100784, nil) return end -- blackout kick for shuffle
				if GS.SIR(119582) and GS.Aura("player", 152173) then GS.Cast("player", 119582, nil) end -- purifying brew
				if GS.SIR(119582) and not GS.PlayerHasTalent(7, 2) and GS.Aura("player", 124274) and not GS.AuraRemaining("player", 115307, 6) then GS.Cast("player", 119582, false, false, false, "SpellToInterrupt") end
				if GS.SIR(115295) and (GetSpellCharges(115295) == 2 or GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 15 or GetSpellCharges(115295) == 1 and guardRechargeTime < 5) then GS.Cast("player", 115295, nil) return end -- guard
				if GS.SIR(115295) and select(2, GS.Resolve()) >= UnitHealthMax("player")*.5 then GS.Cast("target", 115295, false, false, false, "SpellToInterrupt") return end -- guard emergency
				if GS.SCA(121253) and GS.PP(true) - GS.PP() >= 1 and not GS.Aura("player", 152173) then GS.Cast("target", 121253, nil) return end -- keg smash
				if GS.PlayerHasTalent(2, 3) and GS.SIR(123986) and (UnitPower("player")+energyregen) < 100 and GS.IsFacing("player", "target") then GS.Cast("target", 123986, false, false, false, "SpellToInterrupt") return end -- chi burst
				if GS.PlayerHasTalent(2, 1) and (UnitPower("player")+energyregen) < 100 and GS.SIR(115098) then GS.Cast("target", 115098, nil) return end -- chi wave
				if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and (UnitPower("player")+energyregen) < 100 then -- zen sphere
					if not GS.Aura("player", 124081) then GS.Cast("player", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere self
					if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
				end
				if GS.PlayerHasTalent(7, 2) and GS.PP() >= 3 and GS.SCA(157676) then GS.Cast("target", 157676, nil) return end -- chi explosion
				if GS.SCA(100784) and GS.PP() >= 4 then GS.Cast("target", 100784, nil) return end -- blackout kick
				if not GS.PlayerHasTalent(7, 2) and GS.SCA(100784) and GS.AuraRemaining("player", 115307, 3) and GS.SpellCDDuration(121253, nil) >= 1 then GS.Cast("target", 100784, nil) return end -- blackout kick shuffle keg smash
				if GS.PlayerHasTalent(7, 3) and GS.SCA(100784) and GS.Aura("player", 152173) then GS.Cast("target", 100784, nil) return end -- blackout kick spam serenity
				if GS.SIR(115072) and GS.PlayerCount(10) > 0 and GS.PP(true) - GS.PP() >= 1 and GS.SpellCDDuration(121253, nil) >= 1 and (UnitPower("player")+(energyregen*(GS.SpellCDDuration(121253, nil)))) >= 80 then GS.Cast("player", 115072, nil) return end -- expel harm
				if GS.SCA(100780) and GS.PP(true) - GS.PP() >= 1 and GS.SpellCDDuration(121253, nil) >= 1 and GS.SpellCDDuration(115072, nil) >= 1 and (UnitPower("player")+(energyregen*(GS.SpellCDDuration(121253, nil)))) >= 80 then GS.Cast("target", 100780, nil) return end -- jab
				if GS.SCA(100787) then GS.Cast("target", 100787, nil) return end -- tiger palm
			end
		end
	end

	function GS.MONK3() -- windwalker
		if not IsMounted() and not GS.Aura("player", 116781) then GS.Cast("player", 116781, nil) return end -- monk buff

		if GS.Combat() then
			local chibrewcd = 60-(GetTime()-select(3, GetSpellCharges(115399)))
			local _, energyregen = GetPowerRegen()
			local energytimetomax = (UnitPowerMax("player")-UnitPower("player"))/energyregen
			local hurricanecast = 2/(1+GetHaste()*0.01)
			local fofcast = 4/(1+GetHaste()*0.01)
			-- GS.MultiDoT("Storm, Earth, and Fire")

			if GS.ValidTarget() then

				if GS.IsCAOCH() then return end
				StartAttack("target")

				if GS.PlayerHasTalent(6, 2) and GS.CDs and GS.SIR(123904) and GS.UnitIsBoss("target") --[[and GS.Distance("target") <= 10 ]]then GS.Cast(nil, 123904) return end -- Xuen

				if GS.CDs and GS.UnitIsBoss("target") and GS.PlayerHasTalent(7, 3) and GS.PlayerHasTalent(3, 3) and GS.SpellCDDuration(113656, nil) == 0 and (GetTime()-GS.CombatStart) < 20 then
					if not GS.TigerEye() then
						if GS.SIR(116740) and GS.AuraStacks("player", 125195, 9) then GS.Cast("target", 116740, false, false, false, "SpellToInterrupt") return end -- tiger eye for opening sequence
					else
						-- actions.opener+=/use_item,name=beating_heart_of_the_mountain
						if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) then GS.Cast(nil, 20572) return end -- Blood Fury
						if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast(nil, 26297) return end -- Berserking
						if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(155145) and GS.PP(true)-GS.PP() >= 1 then GS.Cast(nil, 155145) return end -- Arcane Torrent
					end
					if GS.SIR(113656) and not GS.AuraRemaining("player", 125359, fofcast) and not GS.AuraRemaining("target", 130320, fofcast, "", "PLAYER") and GS.Aura("player", 152173) and GS.AuraRemaining("player", 152173, 1.5) and (not IsPlayerMoving() or GS.PlayerHasGlyph(159490)) then GS.Cast("target", 113656, false, false, false, "SpellToInterrupt") return end -- fof
					if GS.SCA(100787, "target", interruptCasting) and GS.AuraRemaining("player", 125359, 2) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm for tiger power
					if GS.SCA(107428, "target", interruptCasting) then GS.Cast("target", 107428, false, false, false, "SpellToInterrupt") return end -- rising sun kick
					if GS.SCA(100784, "target", interruptCasting) and (GS.PP(true)-GS.PP() <= 1 and GS.SIR(115399) or GS.Aura("player", 152173)) then GS.Cast("target", 100784, false, false, false, "SpellToInterrupt") return end -- blackout kick
					if GS.SIR(115399) and GS.PP(true)-GS.PP() >= 2 then GS.Cast("target", 115399, false, false, false, "SpellToInterrupt") return end -- chi brew
					if GS.SIR(152173) and GS.PP(true)-GS.PP() <= 2 then GS.Cast("target", 152173, false, false, false, "SpellToInterrupt") return end -- serenity
					if GS.PP(true) - GS.PP() >= 2 and GS.SCA(100780) and not GS.Aura("player", 152173) then GS.Cast(nil, 100780) return end -- jab
					return
				end

				-- actions+=/use_item,name=beating_heart_of_the_mountain,if=buff.tigereye_brew_use.up|target.time_to_die<18
				if GS.CDs and GSR.Race == "Orc" and GS.SIR(20572) and (GS.TigerEye() or (TTD[ObjectPointer("target")] < 18 and GS.UnitIsBoss("target"))) then GS.Cast(nil, 20572) return end -- Blood Fury
				if GS.CDs and GSR.Race == "Troll" and GS.SIR(26297) and (GS.TigerEye() or (TTD[ObjectPointer("target")] < 18 and GS.UnitIsBoss("target"))) then GS.Cast(nil, 26297) return end -- Berserking
				if GS.CDs and GSR.Race == "BloodElf" and GS.SIR(155145) and GS.PP(true)-GS.PP() >= 1 and (GS.TigerEye() or (TTD[ObjectPointer("target")] < 18 and GS.UnitIsBoss("target"))) < 5 then GS.Cast(nil, 155145) return end -- Arcane Torrent
				if GS.PlayerHasTalent(3, 3) and GS.SIR(115399) and UnitPowerMax("player", 12)-GS.PP() >= 2 and not GS.AuraStacks("player", 125195, 17) and ((GetSpellCharges(115399) == 1 and chibrewcd <= 10) or GetSpellCharges(115399) == 2 or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < GetSpellCharges(115399) * 10)) then GS.Cast(nil, 115399) return end -- chi brew
				if GS.SCA(100787) and GS.AuraRemaining("player", 125359, 6.6) then GS.Cast(nil, 100787) return end -- tiger power
				if GS.SIR(116740) and not GS.TigerEye() and GS.AuraStacks("player", 125195, 20) then GS.Cast(nil, 116740) return end -- tiger eye brew dump
				if GS.SIR(116740) and not GS.TigerEye() and GS.AuraStacks("player", 125195, 9) and GS.Aura("player", 152173) then GS.Cast(nil, 116740) return end -- tiger eye brew serenity CD
				-- if GS.SIR(116740) and not GS.TigerEye() and GS.AuraStacks("player", 125195, 9) and GS.SpellCDDuration(113656) == 0 and GS.PP() >= 3 and GS.Aura("target", 130320, "", "PLAYER") and GS.Aura("player", 125359) then GS.Cast(nil, 116740) return end -- tiger eye brew fof CD //I put this under the fof casts
				if GS.PlayerHasTalent(7, 1) and GS.SIR(152175) and GS.SIR(116740) and not GS.TigerEye() and GS.AuraStacks("player", 125195, 9) and GS.Aura("target", 130320, "", "PLAYER") and GS.Aura("player", 125359) then GS.Cast(nil, 116740) return end -- tiger eye hurricane strike
				if GS.SIR(116740) and not GS.TigerEye() and GS.PP() >= 2 and GS.Aura("target", 130320, "", "PLAYER") and GS.Aura("player", 152173) and (GS.AuraStacks("player", 125195, 16) or (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] < 40)) then GS.Cast(nil, 116740) return end
				if GS.SCA(107428) and GS.AuraRemaining("target", 130320, 3, "", "PLAYER") and GS.PP() >= 2 then GS.Cast("target", 107428, nil) return end -- rising sun kick
				if GS.PlayerHasTalent(7, 3) and GS.CDs and GS.UnitIsBoss("target") and GS.SIR(152173) and GS.PP() >= 2 and GS.Aura("target", 130320, "", "PLAYER") and GS.Aura("player", 125359) then GS.Cast(nil, 152173) return end -- SERENITY
				if GS.PlayerHasTalent(6, 1) and GS.SIR(113656) and not GS.AuraRemaining("player", 125359, fofcast) and not GS.AuraRemaining("target", 130320, fofcast, "", "PLAYER") and energytimetomax > fofcast and not GS.Aura("player", 152173) and (not IsPlayerMoving() or GS.PlayerHasGlyph(159490)) then GS.Cast("target", 113656, false, false, false, "SpellToInterrupt") return end -- fof
				-- if GS.SpellCDDuration(115080, nil) == 0 and (GS.PP() >= 3 or GS.PlayerHasGlyph(123391)) and GS.UnitIsBoss("target") and GS.Health("target", maxhealth, true) < 10 then
					-- actions+=/fortifying_brew,if=target.health.percent<10
					-- actions+=/touch_of_death,if=target.health.percent<10
				-- end
				if GS.PlayerHasTalent(7, 1) and GS.SIR(152175, "target", interruptCasting) and energytimetomax > hurricanecast and not GS.AuraRemaining("player", 125359, hurricanecast) and not GS.AuraRemaining("target", 130320, hurricanecast, "", "PLAYER") and not GS.Aura("player", 115288) then GS.Cast("target", 152175, false, false, false, "SpellToInterrupt") return end -- hurricane strike
				if GS.SIR(115288) and GS.SpellCDDuration(113656, nil) > 6 and (not GS.PlayerHasTalent(7, 3) or (not GS.Aura("player", 152173) and GS.SpellCDDuration(152173, nil) > 4)) and UnitPower("player")+energyregen < 50 then GS.Cast("target", 115288, false, false, false, "SpellToInterrupt") return end -- energizing brew
				
				if GS.AoE and GS.PlayerCount(10) >= 3 then
					if GS.PlayerHasTalent(6, 1) then
						if GS.PlayerHasTalent(7, 2) and GS.PP() >= 4 and GS.SCA(152174) and GS.SpellCDDuration(113656, nil) > 4 then GS.Cast(nil, 152174) return end -- chi explosion
						if GS.SIR(116847) then GS.Cast(nil, 116847) return end -- RUSHING JADE WIND
						if not GS.Aura("player", 152173) and energytimetomax > 2 then
							if GS.PlayerHasTalent(2, 1) and GS.SIR(115098) then GS.Cast(nil, 115098) return end -- chi wave
							if GS.PlayerHasTalent(2, 3) and GS.IsFacing("player", "target") and GS.SIR(123986) then GS.Cast(nil, 123986) return end -- chi burst
						end
						if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and energytimetomax > 2 then -- zen sphere
							if not GS.Aura("player", 124081) then GS.Cast("player", 124081) return end -- zen sphere self
							if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
						end
						if GS.SCA(100784, "target", interruptCasting) and (GS.Aura("player", 116768) or GS.Aura("player", 152173)) then GS.Cast("target", 100784, false, false, false, "SpellToInterrupt") return end -- black out kick combo breaker or serenity
						if GS.SCA(100787, "target", interruptCasting) and GS.Aura("player", 118864) and GS.AuraRemaining("player", 118864, 2) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm combo breaker before you lose it
						if GS.SCA(100784, "target", interruptCasting) and GS.PP(true)-GS.PP() < 2 and GS.SpellCDDuration(113656, nil) > 3 then GS.Cast("target", 100784, false, false, false, "SpellToInterrupt") return end -- black out kick dump if not delaying fof
						if GS.PlayerHasTalent(6, 3) and energytimetomax > 2 and GS.SIR(121828) and GS.IsFacing("player", "target") then GS.Cast("target", 121828, false, false, false, "SpellToInterrupt") return end -- chi torpedo
						if GS.SIR(115072) and GS.PP(true)-GS.PP() >= 2 and GS.Health("player", maxhealth, true) < 95 and GS.PlayerCount(10) > 0 then GS.Cast("target", 115072, false, false, false, "SpellToInterrupt") return end -- expel harm
						if GS.PP(true) - GS.PP() >= 2 and GS.SCA(100780) then GS.Cast(nil, 100780) return end -- jab
					else
						if GS.PlayerHasTalent(7, 2) and GS.PP() >= 4 and GS.SCA(152174) and GS.SpellCDDuration(113656, nil) > 4 then GS.Cast(nil, 152174) return end -- chi explosion
						if GS.SCA(107428) and GS.PP() == GS.PP(true) then GS.Cast(nil, 107428) return end -- rising sun kick dump
						if not GS.Aura("player", 152173) and energytimetomax > 2 then
							if GS.PlayerHasTalent(2, 1) and GS.SIR(115098) then GS.Cast(nil, 115098) return end -- chi wave
							if GS.PlayerHasTalent(2, 3) and GS.IsFacing("player", "target") and GS.SIR(123986) then GS.Cast(nil, 123986) return end -- chi burst
						end
						if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and energytimetomax > 2 then -- zen sphere
							if not GS.Aura("player", 124081) then GS.Cast("player", 124081) return end -- zen sphere self
							if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
						end
						if GS.PlayerHasTalent(6, 3) and energytimetomax > 2 and GS.SIR(121828) and GS.IsFacing("player", "target") then GS.Cast("target", 121828, false, false, false, "SpellToInterrupt") return end -- chi torpedo
						if GS.SIR(101546) then GS.Cast(nil, 101546) return end -- spinning crane kick
					end
					return
				end

				if GS.PlayerCount(10) == 2 and GS.PlayerHasTalent(7, 2) then
					if GS.PlayerHasTalent(7, 2) and GS.PP() >= 4 and GS.SCA(152174) and GS.SpellCDDuration(113656, nil) > 4 then GS.Cast(nil, 152174) return end -- chi explosion
					if GS.SCA(100787, "target", interruptCasting) and GS.Aura("player", 118864) and GS.AuraRemaining("player", 118864, 2) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm combo breaker before you lose it
					if not GS.Aura("player", 152173) and energytimetomax > 2 then
						if GS.PlayerHasTalent(2, 1) and GS.SIR(115098) then GS.Cast(nil, 115098) return end -- chi wave
						if GS.PlayerHasTalent(2, 3) and GS.IsFacing("player", "target") and GS.SIR(123986) then GS.Cast(nil, 123986) return end -- chi burst
					end
					if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and energytimetomax > 2 then -- zen sphere
						if not GS.Aura("player", 124081) then GS.Cast("player", 124081) return end -- zen sphere self
						if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
					end
					if GS.PlayerHasTalent(6, 3) and energytimetomax > 2 and GS.SIR(121828) and GS.IsFacing("player", "target") then GS.Cast("target", 121828, false, false, false, "SpellToInterrupt") return end -- chi torpedo
					if GS.SIR(115072) and GS.PP(true)-GS.PP() >= 2 and GS.Health("player", maxhealth, true) < 95 and GS.PlayerCount(10) > 0 then GS.Cast("target", 115072, false, false, false, "SpellToInterrupt") return end -- expel harm
					if GS.PP(true) - GS.PP() >= 2 and GS.SCA(100780) then GS.Cast(nil, 100780) return end -- jab
					return
				end

				if GS.PlayerHasTalent(7, 2) then
					if GS.SCA(152174, "target", interruptCasting) and GS.PP() >= 2 and GS.Aura("player", 159407) and GS.SpellCDDuration(113656, nil) > 2 then GS.Cast("target", 152174, false, false, false, "SpellToInterrupt") return end -- chi explosion combo breaker don't delay fof
					if GS.SCA(100787, "target", interruptCasting) and GS.Aura("player", 118864) and GS.AuraRemaining("player", 118864, 2) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm combo breaker before you lose it
					if not GS.Aura("player", 152173) and energytimetomax > 2 then
						if GS.PlayerHasTalent(2, 1) and GS.SIR(115098) then GS.Cast(nil, 115098) return end -- chi wave
						if GS.PlayerHasTalent(2, 3) and GS.IsFacing("player", "target") and GS.SIR(123986) then GS.Cast(nil, 123986) return end -- chi burst
					end
					if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) and energytimetomax > 2 then -- zen sphere
						if not GS.Aura("player", 124081) then GS.Cast("player", 124081) return end -- zen sphere self
						if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
					end
					if GS.SCA(107428) then GS.Cast(nil, 107428) return end -- rising sun kick
					if GS.SCA(100787, "target", interruptCasting) and GS.PP() == 4 and not GS.Aura("player", 118864) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm dump chi
					if GS.PlayerHasTalent(7, 2) and GS.PP() >= 3 and GS.SCA(152174) and GS.SpellCDDuration(113656, nil) > 4 then GS.Cast(nil, 152174) return end -- chi explosion
					if GS.PlayerHasTalent(6, 3) and energytimetomax > 2 and GS.SIR(121828) and GS.IsFacing("player", "target") then GS.Cast("target", 121828, false, false, false, "SpellToInterrupt") return end -- chi torpedo
					if GS.SIR(115072) and GS.PP(true)-GS.PP() >= 2 and GS.Health("player", maxhealth, true) < 95 and GS.PlayerCount(10) > 0 then GS.Cast("target", 115072, false, false, false, "SpellToInterrupt") return end -- expel harm
					if GS.PP(true) - GS.PP() >= 2 and GS.SCA(100780) then GS.Cast(nil, 100780) return end -- jab
				else
					if GS.SCA(107428) then GS.Cast(nil, 107428) return end -- rising sun kick
					if GS.SCA(100784, "target", interruptCasting) and (GS.Aura("player", 116768) or GS.Aura("player", 152173)) then GS.Cast("target", 100784, false, false, false, "SpellToInterrupt") return end -- black out kick combo breaker or serenity
					if GS.SCA(100787, "target", interruptCasting) and GS.Aura("player", 118864) and GS.AuraRemaining("player", 118864, 2) then GS.Cast("target", 100787, false, false, false, "SpellToInterrupt") return end -- tiger palm combo breaker before you lose it
					if not GS.Aura("player", 152173) then
						if energytimetomax > 2 then
							if GS.PlayerHasTalent(2, 1) and GS.SIR(115098) then GS.Cast(nil, 115098) return end -- chi wave
							if GS.PlayerHasTalent(2, 3) and GS.IsFacing("player", "target") and GS.SIR(123986) then GS.Cast(nil, 123986) return end -- chi burst
							if GS.PlayerHasTalent(2, 2) and GS.SIR(124081) then -- zen sphere
								if not GS.Aura("player", 124081) then GS.Cast("player", 124081) return end -- zen sphere self
								if UnitExists("focus") and not GS.Aura("focus", 124081) then GS.Cast("focus", 124081, false, false, false, "SpellToInterrupt") return end -- zen sphere other tank if he's set to focus
							end
						end
						if GS.PlayerHasTalent(6, 3) and energytimetomax > 2 and GS.SIR(121828) and GS.IsFacing("player", "target") then GS.Cast("target", 121828, false, false, false, "SpellToInterrupt") return end -- chi torpedo
					end
					if GS.PP(true) - GS.PP() < 2 and GS.SCA(100784) then GS.Cast(nil, 100784) return end -- black out kick
					if GS.SIR(115072) and GS.PP(true)-GS.PP() >= 2 and GS.Health("player", maxhealth, true) < 95 and GS.PlayerCount(10) > 0 then GS.Cast("target", 115072, false, false, false, "SpellToInterrupt") return end -- expel harm
					if GS.PP(true) - GS.PP() >= 2 and GS.SCA(100780) then GS.Cast(nil, 100780) return end -- jab
				end
			end
		end
	end

	function GS.DRUID1() -- balance todo: finish cooldowns, time till lunar max argument @druid
		if (not IsMounted() and not GS.Aura("player", 165962)) and (not GetRaidBuffTrayAuraInfo(1) or not GetRaidBuffTrayAuraInfo(9)) and GS.SIR(1126) then GS.Cast("player", 1126, nil) return end -- mark of the wild
		if not (IsMounted() and GS.Aura("player", 165962)) and GetShapeshiftForm() ~= 4 then CastShapeshiftForm(4) return end -- moonkin form
		
		if GS.Combat() then
			GS.MultiDoT("Sunfire")
			GS.MultiDoT("Moonfire")
			if GS.PlayerHasTalent(7, 2) then GS.MultiDoT("Stellar Flare") end
			
			local starsurgeRecharge = 30-(GetTime()-select(3, GetSpellCharges(78674)))

			for i = 1, #GS.Targets do
				if not GS.Druid.StellarFlareThrottle[UnitGUID(GS.Targets[i])] then GS.Druid.StellarFlareThrottle[UnitGUID(GS.Targets[i])] = 0 end
			end

			if GS.ValidTarget() then
				if GS.CDs and GS.Aura("player", 112071) then
					-- actions=potion,name=draenic_intellect,if=buff.celestial_alignment.up
					-- actions+=/blood_fury,if=buff.celestial_alignment.up
					if GSR.Race == "Troll" and GS.SIR(26297) then GS.Cast("target", 26297, false, false, false, "SpellToInterrupt") end
					-- actions+=/arcane_torrent,if=buff.celestial_alignment.up
				end
				-- actions+=/use_item,slot=trinket1
				-- actions+=/use_item,slot=trinket2
				-- actions+=/force_of_nature,if=trinket.stat.intellect.up|charges=3|target.time_to_die<21
				
				-- celestial_alignment = 112071
				-- lunar_empowerment = 164547
				-- solar_empowerment = 164545
				-- solar_peak = 171744
				-- lunar_peak = 171743

				if GS.AoE and #GS.PullEnemies(40, true) > 1 then
					if GS.CDs and GS.SIR(112071) and (GS.UnitIsBoss("target") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] < 20 --[[or lunar_max < 8]]) then GS.Cast("target", 112071, false, false, false, "SpellToInterrupt") return end -- celestial alignment
					-- actions.aoe=celestial_alignment,if=lunar_max<8|target.time_to_die<20
					if GS.PlayerHasTalent(4, 2) and GS.CDs and GS.SIR(102560) and GS.Aura("player", 112071) then GS.Cast("target", 102560, false, false, false, "SpellToInterrupt") return end -- incarnation
					if GS.SIR(8921) and not GS.IsCAOCH() and GS.PP() > 0 then -- sunfire spread
						if GS.SCA(8921, "target", interruptCasting) and GS.AuraRemaining("target", 164815, 8, "Solar", "PLAYER") then GS.Cast("target", 8921, false, false, false, "SpellToInterrupt") return end
						for i = 1, #tNoObjectSunfire do
							if GS.SCA(8921, tNoObjectSunfire[i], interruptCasting) then GS.Cast(tNoObjectSunfire[i], 8921, false, false, false, "SpellToInterrupt") return end
						end
						for i = 1, #tSunfire do
							if GS.SCA(8921, tSunfire[i], interruptCasting) and GS.AuraRemaining(tSunfire[i], 164815, 8, "Solar", "PLAYER") then GS.Cast(tSunfire[i], 8921, false, false, false, "SpellToInterrupt") return end
						end
					end
					if #GS.PullEnemies(40, true) > 2 and not GS.Aura("player", 48505) and GS.SIR(48505) then GS.Cast("target", 48505, false, false, false, "SpellToInterrupt") return end -- starfall for 3+ targets
					if GS.SCA(78674, "target", interruptCasting) and (GetSpellCharges(78674) == 3 or GetSpellCharges(78674) == 2 and starsurgeRecharge < 6) then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge dump
					if GS.SIR(8921) and not GS.IsCAOCH() and GS.PP() <= 0 then -- moonfire spread
						if GS.SCA(8921, "target", interruptCasting) and GS.AuraRemaining("target", 164812, 12, "Lunar", "PLAYER") then GS.Cast("target", 8921, false, false, false, "SpellToInterrupt") return end
						for i = 1, #tNoObjectMoonfire do
							if GS.SCA(8921, tNoObjectMoonfire[i], interruptCasting) then GS.Cast(tNoObjectMoonfire[i], 8921, false, false, false, "SpellToInterrupt") return end
						end
						for i = 1, #tSunfire do
							if GS.SCA(8921, tMoonfire[i], interruptCasting) and GS.AuraRemaining(tMoonfire[i], 164812, 12, "Lunar", "PLAYER") then GS.Cast(tMoonfire[i], 8921, false, false, false, "SpellToInterrupt") return end
						end
					end

					if GS.PlayerHasTalent(7, 2) and GS.SIR(152221) and not GS.IsCAOCH() and (not IsPlayerMoving() or GS.Aura("player", 172106) --[[does druid have any move while casting spells?]]) then -- stellar flare spread
						if GS.SCA(152221, "target", interruptCasting) and GS.Druid.StellarFlareThrottle[UnitGUID("target")] == 0 and GS.AuraRemaining("target", 152221, 7) then GS.Cast("target", 152221, false, false, false, "SpellToInterrupt") return
						else
							for i = 1, #tNoObjectStellarFlare do
								if GS.SCA(152221, tNoObjectStellarFlare[i], interruptCasting) and GS.Druid.StellarFlareThrottle[UnitGUID(tNoObjectStellarFlare[i])] == 0 then GS.Cast(tNoObjectStellarFlare[i], 152221, false, false, false, "SpellToInterrupt") return end
							end
							for i = 1, #tStellarFlare do
								if GS.SCA(152221, tStellarFlare[i], interruptCasting) and GS.Druid.StellarFlareThrottle[UnitGUID(tStellarFlare[i])] == 0 and GS.AuraRemaining(tStellarFlare[i], 152221, 7) then GS.Cast(tStellarFlare[i], 152221, false, false, false, "SpellToInterrupt") return end
							end
						end
					end


					if #GS.PullEnemies(40, true) == 2 and GS.SCA(78674, "target", interruptCasting) then
						if GS.SCA(78674, "target", interruptCasting) and not GS.Aura("player", 164547) and GS.PP() < -20 then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge for lunar empowerment
						if GS.SCA(78674, "target", interruptCasting) and not GS.Aura("player", 164545) and GS.PP() > 40 then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge for solar empowerment
					end
					if GS.SCA(5176, "target", interruptCasting) and ((GS.PP() >= 0 and GS.EclipseChange() > (select(4, GetSpellInfo(5176))*0.001)) or (GS.PP() < 0 and (select(4, GetSpellInfo(5176))*0.001) > GS.EclipseChange())) then GS.Cast("target", 5176, false, false, false, "SpellToInterrupt") return end -- wrath
					if GS.SCA(2912, "target", interruptCasting) and ((GS.PP() <= 0 and GS.EclipseChange() > (select(4, GetSpellInfo(2912))*0.001)) or (GS.PP() > 0 and (select(4, GetSpellInfo(2912))*0.001) > GS.EclipseChange())) then GS.Cast("target", 2912, false, false, false, "SpellToInterrupt") return end -- starfire
					return
				end

				if GS.SCA(78674, "target", interruptCasting) and not GS.Aura("player", 164547) and GS.PP() < -20 then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge for lunar empowerment
				if GS.SCA(78674, "target", interruptCasting) and not GS.Aura("player", 164545) and GS.PP() > 40 then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge for solar empowerment
				if GS.SCA(78674, "target", interruptCasting) and (GetSpellCharges(78674) == 3 or GetSpellCharges(78674) == 2 and starsurgeRecharge < 6) then GS.Cast("target", 78674, false, false, false, "SpellToInterrupt") return end -- starsurge dump
				if GS.CDs and GS.PP() < -40 and GS.SIR(112071) then GS.Cast("target", 112071, false, false, false, "SpellToInterrupt") return end -- celestial alignment
				if GS.PlayerHasTalent(4, 2) and GS.CDs and GS.PP() < 0 and GS.SIR(102560) then GS.Cast("target", 102560, false, false, false, "SpellToInterrupt") return end -- incarnation
				if GS.SCA(8921, "target", interruptCasting) and GS.PP() > 0 and (GS.AuraRemaining("target", 164815, 7, "Solar", "PLAYER") or GS.Aura("player", 171744)) then GS.Cast("target", 93402, false, false, false, "SpellToInterrupt") return end -- sunfire
				if GS.PlayerHasTalent(7, 2) and GS.SCA(152221, "target", interruptCasting) and GS.Druid.StellarFlareThrottle[UnitGUID("target")] == 0 and GS.AuraRemaining("target", 152221, 7, "", "PLAYER") then GS.Cast("target", 152221, false, false, false, "SpellToInterrupt") return end -- stellar flare
				if GS.SCA(8921, "target", interruptCasting) and GS.PP() <= 0 and ((GS.Aura("player", 171743) and GS.AuraRemaining("target", 164812, 20+GS.EclipseChange(), "Lunar", "PLAYER")) or GS.AuraRemaining("target", 164812, 4, "Lunar", "PLAYER") or (GS.Aura("player", 112071) and GS.AuraRemaining("player", 112071, 2) and GS.AuraRemaining("target", 164812, 20+GS.EclipseChange()))) then GS.Cast("target", 8921, false, false, false, "SpellToInterrupt") return end -- moonfire
				if GS.SCA(5176, "target", interruptCasting) and ((GS.PP() >= 0 and GS.EclipseChange() > (select(4, GetSpellInfo(5176))*0.001)) or (GS.PP() < 0 and (select(4, GetSpellInfo(5176))*0.001) > GS.EclipseChange())) then GS.Cast("target", 5176, false, false, false, "SpellToInterrupt") return end -- wrath
				if GS.SCA(2912, "target", interruptCasting) and ((GS.PP() <= 0 and GS.EclipseChange() > (select(4, GetSpellInfo(2912))*0.001)) or (GS.PP() > 0 and (select(4, GetSpellInfo(2912))*0.001) > GS.EclipseChange())) then GS.Cast("target", 2912, false, false, false, "SpellToInterrupt") return end -- starfire
			end
			return
		end
		table.wipe(GS.Druid.StellarFlareThrottle)
	end

	function GS.DRUID2() -- feral -- todo: cut down on loops, add trinkets to force of nature, add healing for that sweet hps @druid 
		if (not IsMounted() and not GS.Aura("player", 165962)) and (not GetRaidBuffTrayAuraInfo(1) or not GetRaidBuffTrayAuraInfo(9)) and GS.SIR(1126) then GS.Cast("player", 1126, nil) return end -- mark of the wild

		if GS.Combat() then
			local cp = GetComboPoints("player")
			GS.Trinkets.Trinket1.cd, GS.Trinkets.Trinket1.dur, GS.Trinkets.Trinket1.enable = GetInventoryItemCooldown("player", 13)
			GS.Trinkets.Trinket2.cd, GS.Trinkets.Trinket2.dur, GS.Trinkets.Trinket2.enable = GetInventoryItemCooldown("player", 14)
			local _, energyregen = GetPowerRegen()
			local energytimetomax = (100-UnitPower("player"))/energyregen

			GS.MultiDoT("Rake")
			GS.MultiDoT("Rip")
			GS.MultiDoT("Thrash")
			if GS.PlayerHasTalent(7, 1) then GS.MultiDoT("Moonfire") end
			local pMultRake = GS.PMultiplier("Rake")
			local pMultRip = GS.PMultiplier("Rip")

			for i = 1, #GS.Targets do
				if not GS.Druid.Rip[GS.Targets[i]] then GS.Druid.Rip[GS.Targets[i]] = 0 end
				if not GS.Druid.Rake[GS.Targets[i]] then GS.Druid.Rake[GS.Targets[i]] = 0 end
			end

			if GS.ValidTarget() then
				if GS.SCA(1822) and (GS.Aura("player", 5215) or GS.Aura("player", 58984)) then -- rake out of stealth
					GS.Druid.Rake[ObjectPointer("target")] = pMultRake*2
					GS.Cast(nil, 1822, nil)
					return
				end
				if GS.Aura("player", 5215) or GS.Aura("player", 58984) then return end -- don't break stealth
				if GS.PlayerHasTalent(4, 3) and GS.SIR(102703) and (GetSpellCharges(102703) == 3 or GS.TTD[ObjectPointer("target")] < 20 --[[or trinket.poc.all.react]]) then GS.Cast(nil, 102703, nil) return end -- force of nature
				StartAttack("target")

				if GS.SIR(5217) and ((UnitPowerMax("player") - GS.PP() >= 60 and not GS.Aura("player", 16864)) or UnitPowerMax("player") - GS.PP() >= 80) and GS.SpellCDDuration(61304, nil) == 0 then -- tiger's fury + trinkets, berserking synced to it
					GS.Cast(nil, 5217, nil)
					if GS.CDs and GS.UnitIsBoss("target") then
						if GS.Trinkets.Trinket1.enable == 1 and GS.Trinkets.Trinket1.cd == 0 then UseInventoryItem(13) end
						if GS.Trinkets.Trinket2.enable == 1 and GS.Trinkets.Trinket2.cd == 0 then UseInventoryItem(14) end
						if GS.SIR(26297) and GSR.Race == "Troll" then GS.Cast("player", 26297, nil) end
					end
				end
				if GS.CDs then -- berserk and incarnation cooldowns
					if GS.PlayerHasTalent(4, 2) and GS.SpellCDDuration(106951, nil) < 10 and energytimetomax > 1 and GS.SIR(102543) then GS.Cast("player", 102543, nil) return end -- incarnation
					if GS.SIR(106951) and GS.Aura("player", 5217) then GS.Cast("player", 106951, nil) return end -- berserk
				end

				--[[-- actions+=/shadowmeld,if=dot.rake.remains<4.5&energy>=35&dot.rake.pmultiplier<2&(buff.bloodtalons.up|!talent.bloodtalons.enabled)&(!talent.incarnation.enabled|cooldown.incarnation.remains>15)&!buff.king_of_the_jungle.up]]

				if GS.SIR(22568) then
					if GS.SCA(22568) and GS.Aura("target", 1079, "", "PLAYER") and GS.AuraRemaining("target", 1079, 3, "", "PLAYER") and GS.Health("target", false, true) < 25 then -- blood in the water
						GS.Cast("target", 22568, nil)
						return
					elseif GS.AoE then
						for i = 1, #tRip do
							if GS.SCA(22568, tRip[i]) and GS.Aura(tRip[i], 1079, "", "PLAYER") and GS.AuraRemaining(tRip[i], 1079, 3, "", "PLAYER") and GS.Health(tRip[i], false, true) < 25 then
								GS.Cast(tRip[i], 22568, nil)
								return
							end
						end
					end
				end

				if GS.PlayerHasTalent(7, 2) and GS.SIR(5185) and GS.Aura("player", 69369) and (cp >= 4 or GS.AuraRemaining("player", 69369, 1.5)) then
					if GSR.Healing then
						local player, hp = nil, 0
						for k,v in ipairs(GS.Players[tanksIndex].Players) do
							if GS.SCA(5185, v.Player, interruptCasting) and v.Stats.Health ~= 0 and v.Stats.HealthRemaining >= hp then
								player = v.Player
								hp = v.Stats.HealthRemaining
							end
						end
						for k,v in ipairs(GS.Players[healersIndex].Players) do
							if GS.SCA(5185, v.Player, interruptCasting) and v.Stats.Health ~= 0 and v.Stats.HealthRemaining >= hp then
								player = v.Player
								hp = v.Stats.HealthRemaining
							end
						end
						for k,v in ipairs(GS.Players[dpsIndex].Players) do
							if GS.SCA(5185, v.Player, interruptCasting) and v.Stats.Health ~= 0 and v.Stats.HealthRemaining >= hp then
								player = v.Player
								hp = v.Stats.HealthRemaining
							end
						end
						for k,v in ipairs(GS.Players) do
							if GS.SCA(5185, v.Player, interruptCasting) and v.Player ~= "Tanks" and v.Player ~= "Healers" and v.Player ~= "DPS" then
								if v.Stats.Health ~= 0 and v.Stats.HealthRemaining >= hp then
									player = v.Player
									hp = v.Stats.HealthRemaining
								end
							end
						end
						if player then GS.Cast(player, 5185, false, false, false, "SpellToInterrupt") return
						else GS.Cast("player", 5185, false, false, false, "SpellToInterrupt") return
						end
					end
					GS.Cast("player", 5185, false, false, false, "SpellToInterrupt")
					return
				end -- healing touch bloodtalons
				if GS.SIR(52610) and GS.AuraRemaining("player", 52610, 3) then GS.Cast("player", 52610, nil) return end -- savage roar

				local activeEnemies = GS.PlayerCount(8)
				local omen = GS.Aura("player", 16864)

				if GS.SIR(106830) then -- thrash
					if GS.AoE and activeEnemies > 1 and omen then -- AoE Omen of Clarity
						for i = 1, #tNoObjectThrash do
							if GS.Distance(tNoObjectThrash[i]) <= 8 then
								GS.Cast(tNoObjectThrash[i], 106830, false, false, false, "SpellToInterrupt")
								return
							end
						end
						for i = 1, #tThrash do
							if GS.Distance(tThrash[i], nil) <= 8 and GS.AuraRemaining(tThrash[i], 106830, 4.5, "Feral, Guardian", "PLAYER") then
								GS.Cast(tThrash[i], 106830, false, false, false, "SpellToInterrupt")
								return
							end
						end
					end

					if not GS.PlayerHasTalent(7, 2) and cp == 5 and omen then -- single target or AoE Omen of Clarity Thrash Refresh
						if GS.Distance("target", nil) <= 8 and GS.AuraRemaining("target", 106830, 4.5, "Feral, Guardian", "PLAYER") then GS.Cast("target", 106830, false, false, false, "SpellToInterrupt") return
						elseif GS.AoE then
							for i = 1, #tNoObjectThrash do
								if GS.Distance(tNoObjectThrash[i]) <= 8 then
									GS.Cast(tNoObjectThrash[i], 106830, false, false, false, "SpellToInterrupt")
									return
								end
							end
							for i = 1, #tThrash do
								if GS.Distance(tThrash[i], nil) <= 8 and GS.AuraRemaining(tThrash[i], 106830, 4.5, "Feral, Guardian", "PLAYER") then
									GS.Cast(tThrash[i], 106830, false, false, false, "SpellToInterrupt")
									return
								end
							end
						end
					end
				end
				if GS.AoE and activeEnemies > 1 then -- needs to be outside for pooling, thrash refresh
					local wait = false
					for i = 1, #tNoObjectThrash do
						if GS.Distance(tNoObjectThrash[i]) <= 8 then
							wait = true
							break
						end
					end
					if not wait then
						for i = 1, #tThrash do
							if GS.Distance(tThrash[i], nil) <= 8 and GS.AuraRemaining(tThrash[i], 106830, 4.5, "Feral, Guardian", "PLAYER") then
								wait = true
								break
							end
						end
					end

					if wait and GS.SIR(106830) then GS.Cast("target", 106830, false, false, false, "SpellToInterrupt") return
						elseif wait then return end
				end -- thrash ending

				if cp == 5 then -- finishers
					if GS.SIR(22568) and ((GS.Aura("player", 106951) and GS.PP() >= 38) or (omen and GS.PP() >= 25) or (GS.PP() >= 50)) then -- ferocious bite blood in the water
						if GS.SCA(22568) and GS.Health("target", false, true) < 25 and GS.Aura("target", 1079, "", "PLAYER") then
							GS.Cast("target", 22568, nil)
							return
						elseif GS.AoE then
							for i = 1, #tRip do
								if GS.SCA(22568, tRip[i]) and GS.Health(tRip[i], false, true) < 25 and GS.Aura(tRip[i], 1079, "", "PLAYER") then
									GS.Cast(tRip[i], 22568, nil)
									return
								end
							end
						end
					end

					if GS.SIR(1079) then
						if GS.SCA(1079) then
							local _, _, _, _, _, _, rakeExpires = GS.Aura("target", 155722, "", "PLAYER")
							if GS.TTD[ObjectPointer("target")] and ((GS.AuraRemaining("target", 1079, 3, "", "PLAYER") and GS.TTD[ObjectPointer("target")] > 18) or (GS.Aura("target", 1079, "", "PLAYER") and GS.AuraRemaining("target", 1079, 7.2, "", "PLAYER") and pMultRip > GS.Druid.Rip[ObjectPointer("target")] and ((GS.TTD[ObjectPointer("target")]-(rakeExpires-GetTime())) > 18))) then -- rip
								GS.Druid.Rip[ObjectPointer("target")] = pMultRip
								GS.Cast("target", 1079, nil)
								return
							end
						end
						if GS.AoE then
							for i = 1, #tRip do
								if GS.SCA(1079, tRip[i]) then
									local _, _, _, _, _, _, rakeExpires = GS.Aura(tRip[i], 155722, "", "PLAYER")
									if GS.TTD[ObjectPointer(tRip[i])] and ((GS.AuraRemaining(tRip[i], 1079, 3, "", "PLAYER") and GS.TTD[tRip[i]] > 18) or (GS.AuraRemaining(tRip[i], 1079, 7.2, "", "PLAYER") and pMultRip > GS.Druid.Rip[ObjectPointer(tRip[i])] and (GS.TTD[tRip[i]]-(rakeExpires-GetTime())) > 18)) then
										GS.Druid.Rip[ObjectPointer(tRip[i])] = pMultRip
										GS.Cast(tRip[i], 1079, nil)
										return
									end
								end
							end
							for i = 1, #tNoObjectRip do
								if GS.SCA(1079, tNoObjectRip[i]) and GS.TTD[ObjectPointer(tNoObjectRip[i])] and GS.TTD[tNoObjectRip[i]] > 18 then
									GS.Druid.Rip[ObjectPointer(tNoObjectRip[i])] = pMultRip
									GS.Cast(tNoObjectRip[i], 1079, nil)
									return
								end
							end
						end
					end

					if GS.SIR(52610) and GS.AuraRemaining("player", 52610, 12.6) and (energytimetomax <= 1 or GS.Aura("player", 106951) or GS.SpellCDDuration(5217, nil) < 3) then GS.Cast("player", 52610, nil) return end -- savage roar
					if GS.SCA(22568) and (GS.PP() >= 50 or (GS.Aura("player", 106951) and GS.PP() >= 38) or (omen and GS.PP() >= 25)) and (energytimetomax <= 1 or GS.Aura("player", 106951) or GS.SpellCDDuration(5217, nil) < 3) then GS.Cast("target", 22568, nil) return end -- ferocious bite
				end

				if not GS.PlayerHasTalent(7, 2) and cp < 5 and GS.SIR(1822) then

					if GS.SCA(1822, "target") then
						if not GS.Aura("target", 155722, "", "PLAYER") then
							if GS.TTD[ObjectPointer("target")] and ((GS.TTD[ObjectPointer("target")] > 3 and activeEnemies < 3) or GS.TTD[ObjectPointer("target")] > 6) then
								GS.Druid.Rake[ObjectPointer("target")] = pMultRake
								GS.Cast("target", 1822, nil)
								return
							end
						else
							local _, _, _, _, _, _, rakeExpires = GS.Aura("target", 155722, "", "PLAYER")
							if (((GS.TTD[ObjectPointer("target")] - (rakeExpires-GetTime())) > 3 and activeEnemies < 3) or (GS.TTD[ObjectPointer("target")] - (rakeExpires-GetTime())) > 6) and (GS.AuraRemaining("target", 155722, 3, "", "PLAYER") or (GS.AuraRemaining("target", 155722, 4.5, "", "PLAYER") and pMultRake > GS.Druid.Rake[ObjectPointer("target")])) then
								GS.Druid.Rake[ObjectPointer("target")] = pMultRake
								GS.Cast("target", 1822, nil)
								return
							end
						end
					end
					if GS.AoE then
						for i = 1, #tRake do
							if GS.SCA(1822, tRake[i]) then
								local _, _, _, _, _, _, rakeExpires = GS.Aura(tRake[i], 155722, "", "PLAYER")
								if (((GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 3 and activeEnemies < 3) or (GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 6) and (GS.AuraRemaining(tRake[i], 155722, 3, "", "PLAYER") or (GS.AuraRemaining(tRake[i], 155722, 4.5, "", "PLAYER") and pMultRake > GS.Druid.Rake[ObjectPointer(tRake[i])])) then
									GS.Druid.Rake[ObjectPointer(tRake[i])] = pMultRake
									GS.Cast(tRake[i], 1822, nil)
									return
								end
							end
						end
						for i = 1, #tNoObjectRake do
							if GS.SCA(1822, tNoObjectRake[i]) then
								if GS.TTD[ObjectPointer(tNoObjectRake[i])] and ((GS.TTD[ObjectPointer(tNoObjectRake[i])] > 3 and activeEnemies < 3) or GS.TTD[ObjectPointer(tNoObjectRake[i])] > 6) then
									GS.Druid.Rake[ObjectPointer(tNoObjectRake[i])] = pMultRake
									GS.Cast(tNoObjectRake[i], 1822, nil)
									return
								end
							end
						end
					end
				end
				-- rake shit

				if GS.PlayerHasTalent(7, 2) then
					if cp < 5 then
						if (not GS.Aura("player", 69369) or GS.Aura("player", 145152)) then
							for i = 1, #tRake do
								if GS.SCA(1822, tRake[i], interruptCasting) and GS.AuraRemaining(tRake[i], 155722, 4.5, "", "PLAYER") then
									local _, _, _, _, _, _, rakeExpires = GS.Aura(tRake[i], 155722, "", "PLAYER")
									if (((GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 3 and activeEnemies < 3) or (GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 6) then
										GS.Cast("target", 1822, false, false, false, "SpellToInterrupt")
										return
									end
								end
							end
							for i = 1, #tNoObjectRake do
								if GS.SCA(1822, tNoObjectRake[i]) then
									if ((GS.TTD[ObjectPointer(tNoObjectRake[i])] > 3 and activeEnemies < 3) or GS.TTD[ObjectPointer(tNoObjectRake[i])] > 6) then
										GS.Druid.Rake[ObjectPointer(tNoObjectRake[i])] = pMultRake
										GS.Cast(tNoObjectRake[i], 1822, nil)
										return
									end
								end
							end
						else
							for i = 1, #tRake do
								if GS.SCA(1822, tRake[i], interruptCasting) and GS.AuraRemaining(tRake[i], 155722, 4.5, "", "PLAYER") and pMultRake > GS.Druid.Rake[ObjectPointer(tRake[i])] then
									local _, _, _, _, _, _, rakeExpires = GS.Aura(tRake[i], 155722, "", "PLAYER")
									if (((GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 3 and activeEnemies < 3) or (GS.TTD[ObjectPointer(tRake[i])] - (rakeExpires-GetTime())) > 6) then
										GS.Druid.Rake[ObjectPointer(tRake[i])] = pMultRake
										GS.Cast("target", 1822, false, false, false, "SpellToInterrupt")
										return
									end
								end
							end
							for i = 1, #tNoObjectRake do
								if GS.SCA(1822, tNoObjectRake[i]) then
									if ((GS.TTD[ObjectPointer(tNoObjectRake[i])] > 3 and activeEnemies < 3) or GS.TTD[ObjectPointer(tNoObjectRake[i])] > 6) then
										GS.Druid.Rake[ObjectPointer(tNoObjectRake[i])] = pMultRake
										GS.Cast(tNoObjectRake[i], 1822, nil)
										return
									end
								end
							end
						end
					elseif omen then
						for i = 1, #tThrash do
							if GS.Distance(tThrash[i], nil) <= 8 and GS.AuraRemaining(tThrash[i], 106830, 4.5, "Feral, Guardian", "PLAYER") then
								GS.Cast(tThrash[i], 106830, false, false, false, "SpellToInterrupt")
								return
							end
						end
						for i = 1, #tNoObjectThrash do
							if GS.Distance(tNoObjectThrash[i]) <= 8 then
								GS.Cast(tNoObjectThrash[i], 106830, false, false, false, "SpellToInterrupt")
								return
							end
						end
					end
				end

				if GS.PlayerHasTalent(7, 1) and cp < 5 and (#tMoonfire+#tNoObjectMoonfire) < 6 then
					if GS.SCA(155625, "target", interruptCasting) and ((not GS.Aura("target", 155625, "", "PLAYER") and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] > 10) or (GS.AuraRemaining("target", 155625, 4.2) and GS.TTD[ObjectPointer("target")] and GS.TTD[ObjectPointer("target")] ~= math.huge and (GS.TTD[ObjectPointer("target")]-((select(7, GS.Aura("target", 155625, "", "PLAYER"))-GetTime()))) > 10)) then
						GS.Cast("target", 155625, false, false, false, "SpellToInterrupt")
						return
					elseif GS.AoE then
						for i = 1, #tMoonfire do
							local _, _, _, _, _, _, rakeExpires = GS.Aura(tMoonfire[i], 155625, "", "PLAYER")
							if GS.SCA(155625, tMoonfire[i], interruptCasting) and GS.AuraRemaining(tMoonfire[i], 155625, 4.2) and GS.TTD[tMoonfire[i]] and GS.TTD[tMoonfire[i]] ~= math.huge and (GS.TTD[tMoonfire[i]] - (rakeExpires-GetTime())) > 10 then
								GS.Cast(tMoonfire[i], 155625, false, false, false, "SpellToInterrupt")
								return
							end
						end
						for i = 1, #tNoObjectMoonfire do
							if GS.SCA(155625, tNoObjectMoonfire[i], interruptCasting) and GS.TTD[tNoObjectMoonfire[i]] and GS.TTD[tNoObjectMoonfire[i]] ~= math.huge and GS.TTD[tNoObjectMoonfire[i]] > 10 then
								GS.Cast(tNoObjectMoonfire[i], 155625, false, false, false, "SpellToInterrupt")
								return
							end
						end
					end
				end

				if GS.PlayerCount(8) == 1 and GS.SCA(1822) and pMultRake > GS.Druid.Rake[ObjectPointer("target")] and cp < 5 then
					GS.Druid.Rake[ObjectPointer("target")] = pMultRake
					GS.Cast("target", 1822, nil)
					return
				end
				if cp < 5 then
					if GS.AoE and GS.SIR(106785) and GS.PlayerCount(8) >= 3 and GS.IsFacing("player", "target") then GS.Cast("target", 106785, nil) return end -- swipe
					if GS.SCA(5221) then GS.Cast("target", 5221, nil) return end -- shred
				end

				-- if GSR.Healing and GS.SIR(774) then -- rejuvenation
				-- 	for k,v in ipairs(GS.Players[tanksIndex].Players) do
				-- 		if GS.SCA(774, v.Player, interruptCasting) and not GS.Aura(v.Player, 774, "", "PLAYER") then GS.Cast(v.Player, 774, false, false, false, "SpellToInterrupt") return end
				-- 	end

				-- 	for k,v in ipairs(GS.Players[dpsIndex].Players) do
				-- 		if ObjectPointer("player") ~= ObjectPointer(v.Player) and v.Stats.HealthPercent < 90 and GS.SCA(774, v.Player, interruptCasting) and not GS.Aura(v.Player, 774, "", "PLAYER")  then GS.Cast(v.Player, 774, false, false, false, "SpellToInterrupt") return end
				-- 	end
				-- end
			end
		end
	end

	function GS.DRUID3() -- guardian  -- todo: cooldowns, barkskin akin to DP prot paladin, healing @tanking @druid
		if (not IsMounted() and not GS.Aura("player", 165962)) and (not GetRaidBuffTrayAuraInfo(1) or not GetRaidBuffTrayAuraInfo(9)) and GS.SIR(1126) then GS.Cast("player", 1126, nil) return end -- mark of the wild

		if GS.Combat() then
			local gcd = 1.5/(1+GetHaste()*.01)

			if GS.ValidTarget() then
				local _, _, _, laceratestacks = GS.Aura("target", 33745, "", "PLAYER")
				StartAttack("target")

				-- actions+=/blood_fury
				-- actions+=/berserking
				-- actions+=/arcane_torrent
				-- actions+=/use_item,slot=trinket2

				-- actions+=/barkskin

				if GS.SCA(6807) and GS.Aura("player", 135286) and GS.PP() >= 80 then GS.Cast(nil, 6807, nil) end
				-- update that ^ to this actions+=/maul,if=buff.tooth_and_claw.react&incoming_damage_1s

				-- actions+=/berserk,if=buff.pulverize.remains>10
				-- actions+=/frenzied_regeneration,if=rage>=80
				-- actions+=/cenarion_ward
				-- actions+=/renewal,if=health.pct<30
				-- actions+=/heart_of_the_wild
				-- actions+=/rejuvenation,if=buff.heart_of_the_wild.up&remains<=0.3*duration
				-- if GS.CDs and GS.SIR(124974) then GS.Cast(nil, 124974, nil) return end -- nature's vigil
				-- actions+=/healing_touch,if=buff.dream_of_cenarius.react&health.pct<30
				if GS.SIR(77758) and not GS.PlayerHasTalent(7, 2) and GS.Distance("target") <= 8 and not GS.Aura("target", 77758, "Feral, Guardian", "PLAYER") then GS.Cast(nil, 77758, nil) return end -- thrash
				if GS.PlayerHasTalent(7, 2) and GS.SCA(80313) and GS.AuraRemaining("player", 158792, 0.5) then GS.Cast(nil, 80313, nil) return end -- pulverize
				if GS.SCA(33745, "target", interruptCasting) and not GS.Aura("target", 33745) then GS.Cast("target", 33745, false, false, false, "SpellToInterrupt") return end -- lacerate if not ticking
				if GS.PlayerHasTalent(7, 2) and GS.SCA(33745) and GS.AuraRemaining("player", 158792, (3-laceratestacks)*gcd) and not GS.Aura("player", 50334) then GS.Cast(nil, 33745, nil) return end -- lacerate
				-- actions+=/incarnation
				if GS.SIR(77758) and GS.Distance("target") <= 8 and not GS.Aura("target", 77758, "Feral, Guardian", "PLAYER") then GS.Cast(nil, 77758, nil) return end -- thrash
				if GS.SCA(33917) then GS.Cast(nil, 33917, nil) return end -- mangle
				if GS.SIR(77758) and GS.Distance("target", nil) <= 8 and GS.AuraRemaining("target", 77758, 4.5, "Feral, Guardian", "PLAYER") then GS.Cast("target", 77758, false, false, false, "SpellToInterrupt") return end -- thrash refresh
				if GS.SCA(33745) then GS.Cast(nil, 33745, nil) return end -- lacerate
			end
		end
	end

-- Rotation Supplements
	function GS.DEATHKNIGHT1CDs()
		if GS.PlayerHasTalent(2, 1) and GS.SIR(49039) then GS.Cast(nil, 49039, nil) return end -- lichborne leech 10%
		if GS.SIR(42650) and not GS.Aura("player", 49222) and not GS.Aura("player", 81256) and not GS.Aura("player", 48792) and not GS.Aura("player", 55233) then GS.Cast(nil, 42650, nil) return end  -- army of the dead
		if GS.SIR(49222) and not GS.Aura("player", 42650) and not GS.Aura("player", 49222) and not GS.Aura("player", 81256) and not GS.Aura("player", 48792) and not GS.Aura("player", 55233) then GS.Cast(nil, 49222, nil) return end -- bone shield
		if GS.SIR(55233) and GS.Health("player", nil, true) < 50 then GS.Cast(nil, 55233, nil) return end -- vampiric blood
		if GS.SIR(48792) and GS.Health("player", nil, true) < 30 and not GS.Aura("player", 42650) and not GS.Aura("player", 81256) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) then GS.Cast(nil, 48792, nil) return end -- icebound fortitude
		if GS.SIR(48982) and GS.Health("player", nil, true) < 50 and not GS.Aura("player", 42650) and not GS.Aura("player", 81256) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) and not GS.Aura("player", 48792) then GS.Cast(nil, 48982, nil) return end --  rune tap
		if GS.SIR(49028) and GS.Health("player", nil, true) < 80 and not GS.Aura("player", 42650) and not GS.Aura("player", 48792) and not GS.Aura("player", 49222) and not GS.Aura("player", 55233) then GS.Cast(nil, 49028, nil) return end -- dancing rune weapon
		if GS.PlayerHasTalent(5, 1) and GS.Health("player", nil, true) < 50 and GS.SIR(48743) then GS.Cast(nil, 48743, nil) return end -- death pact
	end

	function GS.DEATHKNIGHTBOS(mode, blood, frost, unholy, death)
		if string.lower(mode) == "aoe" then
			if GS.PP() < 88 then
				if GS.SIR(43265) then GS.Cast(nil, 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
				if GS.SIR(50842) then GS.Cast(nil, 50842, nil) return end -- blood boil
				if GS.SCA(55090) and unholy == 1 then GS.Cast(nil, 55090, nil) return end -- scourge strike
				if GS.SCA(45477) then GS.Cast(nil, 45477, nil) return end -- icy touch
			end
			if GS.PlayerHasTalent(4, 1) and GS.AuraStacks("player", 114851, 5) and GS.SIR(45529) then GS.Cast(nil, 45529, nil) return end -- blood tap
			if GS.PlayerHasTalent(1, 2) and ((blood == 0 and unholy == 0) or (blood == 0 and frost == 0) or (unholy == 0 and frost == 0)) and GS.SCA(123693, "target", interruptCasting) and (GS.Aura("target", 155159, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER") and GS.Aura("target", 55095, "", "PLAYER")) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech
			if GS.CDs and GS.SIR(47568) and GS.UnitIsBoss("target") and blood == 0 and unholy == 0 and frost == 0 and death == 0 then GS.Cast(nil, 47568) return end -- empower rune weapon
			if GS.SCA(47541, "target", interruptCasting) and GS.Aura("player", 81340) then GS.Cast("target", 47541, false, false, false, "SpellToInterrupt") return end -- death coil if sudden doom
		elseif string.lower(mode) == "single" then
			if GS.SIR(43265) and GS.PP() < 88 then GS.Cast(nil, 43265, GS.SmartAoE(30, 10, true)) return end -- death and decay
			if GS.SCA(85948) and GS.PP() < 77 then GS.Cast(nil, 85948) return end -- festering strike
			if GS.SCA(55090) and GS.PP() < 88 then GS.Cast(nil, 55090, nil) return end -- scourge strike
			if GS.PlayerHasTalent(4, 1) and GS.AuraStacks("player", 114851, 5) and GS.SIR(45529) then GS.Cast(nil, 45529, nil) return end -- blood tap
			if GS.PlayerHasTalent(1, 2) and ((blood == 0 and unholy == 0) or (blood == 0 and frost == 0) or (unholy == 0 and frost == 0)) and GS.SCA(123693, "target", interruptCasting) and (GS.Aura("target", 155159, "", "PLAYER") or GS.Aura("target", 55078, "", "PLAYER") and GS.Aura("target", 55095, "", "PLAYER")) then GS.Cast("target", 123693, false, false, false, "SpellToInterrupt") return end -- plague leech
			if GS.CDs and GS.SIR(47568) and GS.UnitIsBoss("target") and blood == 0 and unholy == 0 and frost == 0 and death == 0 then GS.Cast(nil, 47568) return end -- empower rune weapon
			if GS.SCA(47541, "target", interruptCasting) and GS.Aura("player", 81340) then GS.Cast("target", 47541, false, false, false, "SpellToInterrupt") return end -- death coil if sudden doom
		end
	end

	function GS.DEATHKNIGHTFRAC(x)
		for i = 1, 6 do
			GS.DEATHKNIGHT.Runes.start[i], GS.DEATHKNIGHT.Runes.dur[i], GS.DEATHKNIGHT.Runes.up[i] = GetRuneCooldown(i)
		end
		local bloodFrac, frostFrac, unholyFrac = 0, 0, 0
		local temp = 0

		if GS.DEATHKNIGHT.Runes.start[1] == 0 then bloodFrac = bloodFrac + 1 end
		if GS.DEATHKNIGHT.Runes.start[2] == 0 then bloodFrac = bloodFrac + 1 end

		if GS.DEATHKNIGHT.Runes.start[3] == 0 then frostFrac = frostFrac + 1 end
		if GS.DEATHKNIGHT.Runes.start[4] == 0 then frostFrac = frostFrac + 1 end

		if GS.DEATHKNIGHT.Runes.start[5] == 0 then unholyFrac = unholyFrac + 1 end
		if GS.DEATHKNIGHT.Runes.start[6] == 0 then unholyFrac = unholyFrac + 1 end

		if bloodFrac == 2 and frostFrac == 2 and unholyFrac == 2 then
			return bloodFrac, frostFrac, unholyFrac
		else
			if not x then
				for i = 1, 6 do
					if GS.DEATHKNIGHT.Runes.start[i] ~= 0 then
						temp = 0
						if (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i] > 0 then
							if i == 1 or i == 2 then
								bloodFrac = bloodFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i == 3 or i == 4 then
								unholyFrac = unholyFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i > 4 then
								frostFrac = frostFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							end
						end
					end
				end
				return bloodFrac, frostFrac, unholyFrac
			elseif x == 1 then
				for i = 1, 2 do
					if GS.DEATHKNIGHT.Runes.start[i] ~= 0 then
						temp = 0
						if (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i] > 0 then
							if i == 1 or i == 2 then
								bloodFrac = bloodFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i == 3 or i == 4 then
								unholyFrac = unholyFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i > 4 then
								frostFrac = frostFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							end
						end
					end
				end
				return bloodFrac
			elseif x == 2 then
				for i = 5, 6 do
					if GS.DEATHKNIGHT.Runes.start[i] ~= 0 then
						temp = 0
						if (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i] > 0 then
							if i == 1 or i == 2 then
								bloodFrac = bloodFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i == 3 or i == 4 then
								unholyFrac = unholyFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i > 4 then
								frostFrac = frostFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							end
						end
					end
				end
				return bloodFrac, frostFrac, unholyFrac
			elseif x == 3 then
				for i = 3, 4 do
					if GS.DEATHKNIGHT.Runes.start[i] ~= 0 then
						temp = 0
						if (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i] > 0 then
							if i == 1 or i == 2 then
								bloodFrac = bloodFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i == 3 or i == 4 then
								unholyFrac = unholyFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							elseif i > 4 then
								frostFrac = frostFrac + (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
							end
						end
					end
				end
				return bloodFrac, frostFrac, unholyFrac
			end
		end
		-- (GS.DEATHKNIGHT.Runes.dur[i]-(GS.DEATHKNIGHT.Runes.start[i]+GS.DEATHKNIGHT.Runes.dur[i]-GetTime()))/GS.DEATHKNIGHT.Runes.dur[i]
		-- (dur1-(start1+dur1-GetTime()))/dur1
	end

	function GS.RogueSupplement()
		if not IsModifierKeyDown() then
			GS.Cast("target", 8676, false, false, false, "SpellToInterrupt")
		elseif IsAltKeyDown() then
			GS.Cast("player", 1784, false, false, false, "SpellToInterrupt")
		elseif IsShiftKeyDown() then
			if GS.PlayerHasTalent(4, 2) and GS.SIR(36554) then GS.Cast("target", 36554, false, false, false, "SpellToInterrupt") return end
		elseif IsControlKeyDown() then
			-- GS.SnD = true -- this will cast SnD after the next line
			GS.Frames.Throttle:RegisterEvent("UNIT_COMBO_POINTS") -- this will cast SnD after the next line
			if GS.Spec == 3 and GS.SIR(14183) and GetComboPoints("player") <= 4 then GS.Cast("target", 14183, false, false, false, "SpellToInterrupt") end
			-- C_Timer.After(1, GS.Cast("target", 5171, false, false, false, "SpellToInterrupt")) -- this will cast SnD after the next line
		end
	end

	function GS.TigerEye() -- success
		for i = 1, 40 do
			if UnitBuff("player", i) and select(11, UnitBuff("player", i)) == 116740 then return true
			elseif not UnitBuff("player", i) then return false
			end
		end
	end

	function GS.TTHPG()
		local gcd = GS.SpellCDDuration(61304, nil)
		local cs = GS.SpellCDDuration(35395, nil)
		local judg = GS.SpellCDDuration(20271, nil)
		local wrath = GS.SpellCDDuration(119072, nil)
		local shield = GS.SpellCDDuration(31935, nil)

		local generator = cs
		for i = 1, 4 do
			if i == 1 then
				if cs > judg then generator = judg end
			elseif i == 2 then
				if GS.PlayerHasTalent(5, 2) and generator > wrath then generator = wrath end
			elseif i == 3 then
				if GS.Aura("player", 85416) and generator > shield then generator = shield end
			elseif i == 4 then
				if gcd > generator then generator = gcd end
			end
			if generator == 0 then break end
		end
		return generator
	end

	function GS.PaladinBuffs()
		if not IsMounted() then
			if not GetRaidBuffTrayAuraInfo(7) then GS.Cast("player", 19740, false, false, false, "SpellToInterrupt") return end -- mastery
			if GetRaidBuffTrayAuraInfo(7) and not GS.Aura("player", 19740, "", "PLAYER") and not GetRaidBuffTrayAuraInfo(1) then GS.Cast("player", 20217, false, false, false, "SpellToInterrupt") return end -- stats
		end
	end

	function GS.ShamanHealing(spell)
		if spell == "Riptide" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(61295)
			local initHealing, overTime = string.match(GSSpellsTextLeft4:GetText(), "(%d+[,.]?%d*).-(%d+[,.]?%d*)")
			initHealing = string.gsub(initHealing, ",", "")
			if GS.Aura("player", 73685) then initHealing = initHealing*2 end
			overTime = string.gsub(overTime, ",", "")
			if GS.Aura("player", 73685) then overTime = overTime*2 end
			return tonumber(initHealing), tonumber(overTime)
		elseif spell == "Healing Surge" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(8004)
			local initHealing = string.match(GSSpellsTextLeft4:GetText(), "(%d+[,.]?%d*)")
			initHealing = string.gsub(initHealing, ",", "")
			if GS.Aura("player", 73685) then initHealing = initHealing*2 end
			return tonumber(initHealing)
		elseif spell == "Unleash Life" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(73685)
			local initHealing = string.match(GSSpellsTextLeft4:GetText(), "(%d+[,.]?%d*)")
			initHealing = string.gsub(initHealing, ",", "")
			return tonumber(initHealing)
		end
	end

	function GS.PaladinHealing(spell)
		if spell == "Holy Shock" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(20473)
			local healing = string.match(GSSpellsTextLeft4:GetText(), "(%d+[,.]?%d*) healing")
			healing = string.gsub(healing, ",", "")
			return tonumber(healing)
		elseif spell == "Holy Light" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(82326)
			local healing = string.match(GSSpellsTextLeft4:GetText(), "%d+[,.]?%d*")
			healing = string.gsub(healing, ",", "")
			return tonumber(healing)
		end
	end

	function GS.EclipseChange()
		local direction, energy, euphoria = GetEclipseDirection(), GS.PP(), GS.PlayerHasTalent(7, 1)
		if euphoria then
			if direction == "moon" then
				if energy > 0 then
					return energy/25
				else
					local remaining = 4-math.abs(energy/25)
					return remaining+4
				end
			elseif direction == "sun" then
				if energy < 0 then
					return math.abs(energy/25)
				else
					local remaining = 4-energy/25
					return remaining+4
				end
			else
				return nil
			end
		else
			if direction == "moon" then
				if energy > 0 then
					return energy/12.5
				else
					local remaining = 8-math.abs(energy/12.5)
					return remaining+8
				end
			elseif direction == "sun" then
				if energy < 0 then
					return energy/12.5
				else
					local remaining = 8-energy/12.5
					return remaining+8
				end
			else
				return nil
			end
		end
	end

	function GS.DruidHealing(spell)
		if spell == "Feral Healing Touch" then
			GSSpells:ClearLines()
			GSSpells:SetSpellByID(5185)
			local healing = string.match(GSSpellsTextLeft4:GetText(), "%d+[.,]?%d*")
			healing = string.gsub(healing, ",", "")
			return tonumber(healing)
		end
	end

	function GS.ShadowWordDeath()
		if GS.AoE then
			for i = 1, #GS.Targets do
				if GS.Health(GS.Targets[i], maxhealth, true) <= 20 then return true end
			end
		else
			if GS.Health("target", maxhealth, true) <= 20 then return true end
		end
		return false
	end

-- ACE STUFF
	local options = {
		type = "group",
		name = "GStar Rotations Settings",
		args = {
			General = {
				name = "General Settings",
				type = "group",
				order = 1,
				args = {
					InterruptTrainer = {
						order = 10,
						type = "toggle",
						name = "Interrupt",
						desc = "Use SoO automatic interrupt?",
						descStyle = "inline",
						get = function() return GSR.Interrupt end,
						set = function(i, v) GSR.Interrupt = v end
					},
					TauntTrainer = {
						order = 11,
						type = "toggle",
						name = "Taunt",
						desc = "Use SoO automatic taunt?\n(Set other tank as focus.)",
						descStyle = "inline",
						get = function() return GSR.Taunt end,
						set = function(i,v) GSR.Taunt = v end
					},
					ThokThrottle = {
						order = 12,
						type = "toggle",
						name = "Thok",
						desc = "Use automatic stop casting for Thok? (Not 100% success rate.)",
						descStyle = "inline",
						get = function() return GSR.Thok end,
						set = function(i,v) GSR.Thok = v end
					},
					Healing = {
						order = 13,
						type = "toggle",
						name = "Healing",
						desc = "Enable this if you're using this addon to heal.",
						descStyle = "inline",
						get = function() return GSR.Healing end,
						set = function(i,v) GSR.Healing = v end
					},
					Newline1 = {
						order = 14,
						type ="header",
						name = ""
					},
					TimelessIsle = {
						order = 15,
						type = "execute",
						name = "Timeless Isle Buffs",
						func = function() if not GSR.TimelessIsle then print("Timeless Isle Buffs script loaded.") GSR.TimelessIsle = not GSR.TimelessIsle return else print("Timeless Isle Buffs script unloaded.") GSR.TimelessIsle = not GSR.TimelessIsle return end end
					},
					Slowfall = {
						order = 16,
						type = "execute",
						name = "Slowfall",
						func = function() if not GSR.Slowfall then print("Slowfall script loaded.") GSR.Slowfall = not GSR.Slowfall return else print("Slowfall script unloaded.") GSR.Slowfall = not GSR.Slowfall return end end
					},
					RunTutorial = {
						order = 17,
						type = "execute",
						name = "Run Tutorial",
						func = function() GS.TextBox("tutorial", true) end
					}
				}
			},
			Paladin = {
				name = "Paladin Settings",
				type = "group",
				order = 100,
				hidden = function() if GSR.Class == "PALADIN" then return false else return true end end,
				args = {
					DivineProtection = {
						order = 111,
						type = "toggle",
						name = "Divine Protection Auto Use",
						get = function() return GSR.DivineProtection end,
						set = function(i,v) GSR.DivineProtection = v end
					},
					Mode = {
						order = 110,
						type = "select",
						name = "Rotation Mode",
						values = {"Mixed Mode","Max DPS","Max Survival"},
						get = function() return GSR.ProtectionPaladinMode or 1 end,
						set = function(i,v) GSR.ProtectionPaladinMode = v end
					}
				}
			},
			Warrior = {
				name = "Warrior Settings",
				type = "group",
				order = 200,
				hidden = function() if GSR.Class == "WARRIOR" then return false else return true end end,
				args = {
					GladStance = {
						order = 210,
						type = "toggle",
						name = "Gladiator Stance",
						get = function () return GSR.GladStance end,
						set = function(i, v) GSR.GladStance = v end
					}
				}
			}
		}
	}

	AC:RegisterOptionsTable("GS_Settings", options)

	function RotationToggle(command)
		command = command:lower()

		if command == "!gs toggle" or command == "!gs t" then
			if GS.Start then
				GS.Start = false
				GS.AnimationMaintenance("off")
				print("GStar Rotations: Off")
				return true
			else
				GS.Start = true
				GS.AnimationMaintenance("on")
				print("GStar Rotations: On")
				return true
			end
		end

		if command == "!gs aoe" then GS.ToggleAoE() return true end

		if command == "!gs cds" then GS.ToggleCDs() return true end

		if command == "!gs debug" or command == "!gs d" then
			GSD = GS
			return true
		end

		if command == "!gs" then
			ACD:Open("GS_Settings")
			return true
		end
	end

-- Todo: move stuff out of the lua environment to the GS table @framework
-- todo: check to see if we can pull info from dbm timer
-- todo: figure out how to get the powercost of a spell @framework
-- todo: decide on potion usage for rotations